From d1f9d0024a14d76111064c09f9e057b807cde338 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Fri, 12 Apr 2019 10:46:41 +0200 Subject: [PATCH 001/197] fix issue with seed --- .../android/model/utils/Seed.kt | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt index 2604de61..102ebb18 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt @@ -26,9 +26,28 @@ class Seed(var context:Context) : Realm.Transaction { } } + /** + * Return the locale currency, or en_US if there + */ + private fun getLocaleCurrency() : java.util.Currency { + return try { + java.util.Currency.getInstance(Locale.getDefault()) + } catch (ex: Exception) { + when (Locale.getDefault().language) { + "en" -> java.util.Currency.getInstance(Locale("en", "US")) + "fr" -> java.util.Currency.getInstance(Locale("fr", "FR")) + "es" -> java.util.Currency.getInstance(Locale("es", "ES")) + "de" -> java.util.Currency.getInstance(Locale("de", "DE")) + "ja" -> java.util.Currency.getInstance(Locale("ja", "JP")) + "zh" -> java.util.Currency.getInstance(Locale("zh", "CN")) + else -> java.util.Currency.getInstance(Locale("en", "US")) + } + } + } + private fun createDefaultCurrencyAndBankroll(realm: Realm) { // Currency - val localeCurrency = java.util.Currency.getInstance(Locale.getDefault()) + val localeCurrency = getLocaleCurrency() val defaultCurrency = Currency() defaultCurrency.code = localeCurrency.currencyCode realm.insertOrUpdate(defaultCurrency) From ae009f468f755736090a44f47c503f078afdebad Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Fri, 12 Apr 2019 16:52:52 +0200 Subject: [PATCH 002/197] fix settings crash --- .../android/model/realm/Session.kt | 2 +- .../android/model/utils/Seed.kt | 21 ++----------------- .../android/util/CurrencyUtils.kt | 20 +++++++++++++++++- .../android/util/Preferences.kt | 15 ++++++++++++- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 8bf81de2..486aca1b 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -486,7 +486,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat * Return the formatted blinds */ fun getBlinds(): String { - val currencyCode = bankroll?.currency?.code ?: Currency.getInstance(Locale.getDefault()).currencyCode + val currencyCode = bankroll?.currency?.code ?: CurrencyUtils.getLocaleCurrency().currencyCode val currencySymbol = Currency.getInstance(currencyCode).symbol return if (cgSmallBlind == null) NULL_TEXT else "$currencySymbol ${cgSmallBlind?.formatted()}/${cgBigBlind?.round()}" } diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt index 102ebb18..ecf5fbc7 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt @@ -6,6 +6,8 @@ import io.realm.kotlin.where import net.pokeranalytics.android.R import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.model.realm.Currency +import net.pokeranalytics.android.util.CurrencyUtils +import net.pokeranalytics.android.util.CurrencyUtils.Companion.getLocaleCurrency import net.pokeranalytics.android.util.Preferences import java.util.* @@ -26,25 +28,6 @@ class Seed(var context:Context) : Realm.Transaction { } } - /** - * Return the locale currency, or en_US if there - */ - private fun getLocaleCurrency() : java.util.Currency { - return try { - java.util.Currency.getInstance(Locale.getDefault()) - } catch (ex: Exception) { - when (Locale.getDefault().language) { - "en" -> java.util.Currency.getInstance(Locale("en", "US")) - "fr" -> java.util.Currency.getInstance(Locale("fr", "FR")) - "es" -> java.util.Currency.getInstance(Locale("es", "ES")) - "de" -> java.util.Currency.getInstance(Locale("de", "DE")) - "ja" -> java.util.Currency.getInstance(Locale("ja", "JP")) - "zh" -> java.util.Currency.getInstance(Locale("zh", "CN")) - else -> java.util.Currency.getInstance(Locale("en", "US")) - } - } - } - private fun createDefaultCurrencyAndBankroll(realm: Realm) { // Currency val localeCurrency = getLocaleCurrency() diff --git a/app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt b/app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt index 861ada82..c3fc3dd2 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt @@ -13,7 +13,7 @@ class CurrencyUtils { * return the currency associated with this bankroll */ fun getCurrency(bankroll: Bankroll? = null) : Currency { - val currencyCode = bankroll?.currency?.code ?: Currency.getInstance(Locale.getDefault()).currencyCode + val currencyCode = bankroll?.currency?.code ?: CurrencyUtils.getLocaleCurrency().currencyCode return Currency.getInstance(currencyCode) } @@ -40,6 +40,24 @@ class CurrencyUtils { return currencyFormatter } + /** + * Return the locale currency, or en_US if there + */ + fun getLocaleCurrency() : java.util.Currency { + return try { + java.util.Currency.getInstance(Locale.getDefault()) + } catch (ex: Exception) { + when (Locale.getDefault().language) { + "en" -> java.util.Currency.getInstance(Locale("en", "US")) + "fr" -> java.util.Currency.getInstance(Locale("fr", "FR")) + "es" -> java.util.Currency.getInstance(Locale("es", "ES")) + "de" -> java.util.Currency.getInstance(Locale("de", "DE")) + "ja" -> java.util.Currency.getInstance(Locale("ja", "JP")) + "zh" -> java.util.Currency.getInstance(Locale("zh", "CN")) + else -> java.util.Currency.getInstance(Locale("en", "US")) + } + } + } } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt index adfe3790..149c6062 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt @@ -69,7 +69,20 @@ class Preferences { return it } } - currencyLocale = Locale.getDefault() + + currencyLocale = try { + Locale.getDefault() + } catch (ex: Exception) { + when (Locale.getDefault().language) { + "en" -> Locale("en", "US") + "fr" -> Locale("fr", "FR") + "es" -> Locale("es", "ES") + "de" -> Locale("de", "DE") + "ja" -> Locale("ja", "JP") + "zh" -> Locale("zh", "CN") + else -> Locale("en", "US") + } + } return currencyLocale!! } From db3689063c3d4fcd4608740e782e9b123b8a0e27 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 12 Apr 2019 16:59:30 +0200 Subject: [PATCH 003/197] version 11 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 18f07644..a8146d59 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 8 + versionCode 11 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From 457d02dd071df810b07feddcd20aea546d1bd12d Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Fri, 12 Apr 2019 18:38:24 +0200 Subject: [PATCH 004/197] fix crash in settings when locale is badly initialized --- .../net/pokeranalytics/android/util/Preferences.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt index 149c6062..a0808da5 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt @@ -70,9 +70,16 @@ class Preferences { } } - currencyLocale = try { - Locale.getDefault() + val defaultLocale = Locale.getDefault() + val defaultCurrency = try { + Currency.getInstance(defaultLocale) } catch (ex: Exception) { + null + } + + currencyLocale = defaultCurrency?.let { + defaultLocale + } ?: run { when (Locale.getDefault().language) { "en" -> Locale("en", "US") "fr" -> Locale("fr", "FR") @@ -83,6 +90,7 @@ class Preferences { else -> Locale("en", "US") } } + return currencyLocale!! } From ae0d8d3e4062332eb622f795f2c42571c0303387 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 15 Apr 2019 10:08:42 +0200 Subject: [PATCH 005/197] version --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index a8146d59..d8bf7d72 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 11 + versionCode 12 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From 5125926f82b5164af90d3d7990f2839207c40925 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 15 Apr 2019 11:22:14 +0200 Subject: [PATCH 006/197] Fixes crash when setting empty value on net result --- .../android/model/realm/Session.kt | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 486aca1b..0cc949d8 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -759,7 +759,13 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } SessionRow.BUY_IN -> { val localResult = if (this.result != null) this.result as Result else realm.createObject(Result::class.java) - localResult.buyin = value as Double? + + if (value == null) { + localResult.buyin = null + } else { + localResult.buyin = (value as String).toDouble() + } + this.result = localResult this.updateRowRepresentation() } @@ -776,7 +782,13 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } SessionRow.NET_RESULT -> { this.result?.let { result -> - result.netResult = (value as String).toDouble() + + if (value == null) { + result.netResult = null + } else { + result.netResult = (value as String).toDouble() + } + } } SessionRow.COMMENT -> comment = value as String? ?: "" @@ -819,7 +831,12 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat SessionRow.TABLE_SIZE -> tableSize = value as Int? SessionRow.TIPS -> { val localResult = if (result != null) result as Result else realm.createObject(Result::class.java) - localResult.tips = value as Double? + if (value == null) { + localResult.tips = null + } else { + localResult.tips = (value as String).toDouble() + } + result = localResult } SessionRow.TOURNAMENT_NAME -> tournamentName = value as TournamentName? From f7180e8325c92aa73171537ddab2059d35f39b90 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 15 Apr 2019 14:19:10 +0200 Subject: [PATCH 007/197] Fixing migration missing field --- .../android/model/migrations/PokerAnalyticsMigration.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index 4588fd95..39f185d1 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -41,6 +41,7 @@ class PokerAnalyticsMigration : RealmMigration { it.renameField("filterElements", "filterConditions") } schema.get("SessionSet")?.let { + it.addField("id", String::class.java).setRequired("id", true) it.addPrimaryKey("id") } currentVersion++ From a951a91865f37325c64ba64901968e15b6018a94 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 15 Apr 2019 14:19:29 +0200 Subject: [PATCH 008/197] bumping version code to 13 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index d8bf7d72..c7169b95 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 12 + versionCode 13 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From 50feb6dc80dbbef9bd052ba1613652b2709a470d Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 15 Apr 2019 17:20:28 +0200 Subject: [PATCH 009/197] Fixes crash when rate is null --- .../android/ui/fragment/BankrollDataFragment.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt index 586888cb..14283c47 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt @@ -117,12 +117,9 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS return when (row) { SimpleRow.NAME -> row.editingDescriptors(mapOf("defaultValue" to this.bankroll.name)) BankrollRow.RATE -> { - - this.bankroll.currency?.rate?.let { rate -> - row.editingDescriptors(mapOf("defaultValue" to CurrencyUtils.getCurrencyRateFormatter().format(rate))) - } ?: run { - row.editingDescriptors(mapOf()) - } + val rate = this.bankroll.currency?.rate ?: 1.0 + val rateFormatted = CurrencyUtils.getCurrencyRateFormatter().format(rate) + row.editingDescriptors(mapOf("defaultValue" to rateFormatted)) } else -> null } From 0eba63f112131995f619e4367e05cf9f9989e8d4 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 15 Apr 2019 18:02:24 +0200 Subject: [PATCH 010/197] Harmonizing number capture and management + fixing crashes --- .../android/model/realm/Result.kt | 17 ++- .../android/model/realm/Session.kt | 42 ++---- .../BottomSheetNumericTextFragment.kt | 80 +++++++++++ .../components/bottomsheet/BottomSheetType.kt | 3 +- .../ui/view/rowrepresentable/SessionRow.kt | 130 ++++++++++++------ 5 files changed, 191 insertions(+), 81 deletions(-) create mode 100644 app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt index 1a3ecdb5..e0641348 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt @@ -80,13 +80,16 @@ open class Result : RealmObject() { private fun computeNet() { val transactionsSum = transactions.sumByDouble { it.amount } - this.netResult?.let { - this.net = it + transactionsSum - } ?: run { - val buyin = this.buyin ?: 0.0 - val cashOut = this.cashout ?: 0.0 - this.net = cashOut - buyin + transactionsSum - } + + val isLive = this.session?.bankroll?.live ?: true + if (isLive) { + val buyin = this.buyin ?: 0.0 + val cashOut = this.cashout ?: 0.0 + this.net = cashOut - buyin + transactionsSum + } else { + val netResult = this.netResult ?: 0.0 + this.net = netResult + transactionsSum + } // Precompute results this.session?.computeStats() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 0cc949d8..0244b20e 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -627,7 +627,8 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat SessionRow.BLINDS -> getBlinds() SessionRow.BREAK_TIME -> if (this.breakDuration > 0.0) this.breakDuration.toMinutes() else NULL_TEXT SessionRow.BUY_IN -> this.result?.buyin?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT - SessionRow.CASHED_OUT, SessionRow.PRIZE, SessionRow.NET_RESULT -> this.result?.cashout?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT + SessionRow.CASHED_OUT, SessionRow.PRIZE -> this.result?.cashout?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT + SessionRow.NET_RESULT -> this.result?.netResult?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT SessionRow.COMMENT -> if (this.comment.isNotEmpty()) this.comment else NULL_TEXT SessionRow.END_DATE -> this.endDate?.shortDateTime() ?: NULL_TEXT SessionRow.GAME -> getFormattedGame() @@ -664,7 +665,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat override fun actionIconForRow(row: RowRepresentable): Int? { return when (row) { SessionRow.START_DATE, SessionRow.END_DATE -> { - net.pokeranalytics.android.R.drawable.ic_close + R.drawable.ic_close } else -> null } @@ -699,14 +700,14 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat SessionRow.BUY_IN -> row.editingDescriptors(mapOf( "bb" to cgBigBlind, "fee" to this.tournamentEntryFee, - "ratedBuyin" to ratedBuyin + "ratedBuyin" to result?.buyin )) SessionRow.BREAK_TIME -> row.editingDescriptors(mapOf()) SessionRow.CASHED_OUT, SessionRow.PRIZE -> row.editingDescriptors(mapOf( - "defaultValue" to result?.cashout?.round() + "defaultValue" to result?.cashout )) SessionRow.NET_RESULT -> row.editingDescriptors(mapOf( - "defaultValue" to result?.netResult?.round() + "defaultValue" to result?.netResult )) SessionRow.COMMENT -> row.editingDescriptors(mapOf( "defaultValue" to this.comment)) @@ -759,43 +760,26 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } SessionRow.BUY_IN -> { val localResult = if (this.result != null) this.result as Result else realm.createObject(Result::class.java) - - if (value == null) { - localResult.buyin = null - } else { - localResult.buyin = (value as String).toDouble() - } - + localResult.buyin = value as Double? this.result = localResult this.updateRowRepresentation() } SessionRow.CASHED_OUT, SessionRow.PRIZE -> { val localResult = if (this.result != null) this.result as Result else realm.createObject(Result::class.java) - if (value == null) { - localResult.cashout = null - } else { - localResult.cashout = (value as String).toDouble() - } + localResult.cashout = value as Double? this.result = localResult } SessionRow.NET_RESULT -> { this.result?.let { result -> - - if (value == null) { - result.netResult = null - } else { - result.netResult = (value as String).toDouble() - } - + result.netResult = value as Double? } } SessionRow.COMMENT -> comment = value as String? ?: "" SessionRow.END_DATE -> if (value is Date?) { this.endDate = value - } SessionRow.GAME -> { if (value is ArrayList<*>) { @@ -814,7 +798,6 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } else if (value == null) { limit = null game = null - } } SessionRow.INITIAL_BUY_IN -> tournamentEntryFee = if (value == null) null else (value as String).toDouble() @@ -831,12 +814,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat SessionRow.TABLE_SIZE -> tableSize = value as Int? SessionRow.TIPS -> { val localResult = if (result != null) result as Result else realm.createObject(Result::class.java) - if (value == null) { - localResult.tips = null - } else { - localResult.tips = (value as String).toDouble() - } - + localResult.tips = value as Double? result = localResult } SessionRow.TOURNAMENT_NAME -> tournamentName = value as TournamentName? diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt new file mode 100644 index 00000000..8e953d6c --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt @@ -0,0 +1,80 @@ +package net.pokeranalytics.android.ui.fragment.components.bottomsheet + +import android.os.Bundle +import android.text.InputType +import android.view.LayoutInflater +import android.view.View +import android.view.inputmethod.EditorInfo +import androidx.core.widget.addTextChangedListener +import kotlinx.android.synthetic.main.bottom_sheet_edit_text.* +import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.* +import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.RowRepresentableEditDescriptorException +import java.text.NumberFormat + + +class BottomSheetNumericTextFragment : BottomSheetFragment() { + + private var value: Double? = null + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initData() + initUI() + } + + override fun onStart() { + super.onStart() + editText1.requestFocus() + } + + override fun getValue(): Any? { + return this.value + } + + /** + * Init data + */ + private fun initData() { + } + + /** + * Init UI + */ + private fun initUI() { + val data = getData()?:throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor not found") + if (data.size != 1) { + throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor inconsistency") + } + + LayoutInflater.from(requireContext()).inflate(R.layout.bottom_sheet_edit_text, view?.bottomSheetContainer, true) + + data[0].hint?.let { editText1.hint = getString(it) } + editText1.inputType = data[0].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES + editText1.addTextChangedListener { + + this.value = try { + editText1.text.toString().toDouble() + } catch (e: Exception) { + null + } + + } + data[0].defaultValue?.let { + val formatter = NumberFormat.getNumberInstance() + formatter.isGroupingUsed = false + editText1.setText(formatter.format(it)) + } + + editText1.setOnEditorActionListener { _, actionId, _ -> + if (actionId == EditorInfo.IME_ACTION_DONE) { + delegate.onRowValueChanged(getValue(), row) + dismiss() + true + } else { + false + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetType.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetType.kt index 8a678127..41ce26f5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetType.kt @@ -11,6 +11,7 @@ enum class BottomSheetType { EDIT_TEXT { override fun newInstance() = BottomSheetEditTextFragment()}, EDIT_TEXT_MULTI_LINES { override fun newInstance() = BottomSheetEditTextMultiLinesFragment()}, DOUBLE_EDIT_TEXT { override fun newInstance() = BottomSheetDoubleEditTextFragment()}, + NUMERIC_TEXT { override fun newInstance() = BottomSheetNumericTextFragment()}, SUM { override fun newInstance() = BottomSheetSumFragment()}; abstract fun newInstance(): BottomSheetFragment @@ -26,7 +27,7 @@ enum class BottomSheetType { val addRequired : Boolean get() = when (this) { - EDIT_TEXT, DOUBLE_EDIT_TEXT, EDIT_TEXT_MULTI_LINES, GRID, LIST_STATIC, SUM -> false + EDIT_TEXT, NUMERIC_TEXT, DOUBLE_EDIT_TEXT, EDIT_TEXT_MULTI_LINES, GRID, LIST_STATIC, SUM -> false else -> true } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SessionRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SessionRow.kt index 7eb0f035..27b2c73f 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SessionRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SessionRow.kt @@ -49,17 +49,39 @@ enum class SessionRow : RowRepresentable { return when (session.getState()) { SessionState.PENDING, SessionState.PLANNED -> { arrayListOf( - GAME, INITIAL_BUY_IN, LOCATION, BANKROLL, TABLE_SIZE, TOURNAMENT_TYPE, TOURNAMENT_NAME, TOURNAMENT_FEATURE, - START_DATE, END_DATE + GAME, + INITIAL_BUY_IN, + LOCATION, + BANKROLL, + TABLE_SIZE, + TOURNAMENT_TYPE, + TOURNAMENT_NAME, + TOURNAMENT_FEATURE, + START_DATE, + END_DATE ) } SessionState.STARTED, SessionState.PAUSED, SessionState.FINISHED -> { arrayListOf( - PRIZE, BUY_IN, POSITION, PLAYERS, TIPS, + PRIZE, + BUY_IN, + POSITION, + PLAYERS, + TIPS, SeparatorRowRepresentable(), - GAME, INITIAL_BUY_IN, LOCATION, BANKROLL, TABLE_SIZE, TOURNAMENT_TYPE, TOURNAMENT_NAME, TOURNAMENT_FEATURE, + GAME, + INITIAL_BUY_IN, + LOCATION, + BANKROLL, + TABLE_SIZE, + TOURNAMENT_TYPE, + TOURNAMENT_NAME, + TOURNAMENT_FEATURE, SeparatorRowRepresentable(), - START_DATE, END_DATE, BREAK_TIME, COMMENT + START_DATE, + END_DATE, + BREAK_TIME, + COMMENT ) } } @@ -73,15 +95,33 @@ enum class SessionRow : RowRepresentable { val liveBankroll = session.bankroll?.live ?: false return if (liveBankroll) { arrayListOf( - CASHED_OUT, BUY_IN, TIPS, + CASHED_OUT, + BUY_IN, + TIPS, SeparatorRowRepresentable(), - GAME, BLINDS, LOCATION, BANKROLL, TABLE_SIZE, START_DATE, END_DATE, BREAK_TIME, COMMENT + GAME, + BLINDS, + LOCATION, + BANKROLL, + TABLE_SIZE, + START_DATE, + END_DATE, + BREAK_TIME, + COMMENT ) } else { arrayListOf( NET_RESULT, SeparatorRowRepresentable(), - GAME, BLINDS, LOCATION, BANKROLL, TABLE_SIZE, START_DATE, END_DATE, BREAK_TIME, COMMENT + GAME, + BLINDS, + LOCATION, + BANKROLL, + TABLE_SIZE, + START_DATE, + END_DATE, + BREAK_TIME, + COMMENT ) } } @@ -131,7 +171,7 @@ enum class SessionRow : RowRepresentable { override val bottomSheetType: BottomSheetType get() { return when (this) { - NET_RESULT, CASHED_OUT, INITIAL_BUY_IN, BREAK_TIME, POSITION, PLAYERS, PRIZE -> BottomSheetType.EDIT_TEXT + NET_RESULT, CASHED_OUT, INITIAL_BUY_IN, BREAK_TIME, POSITION, PLAYERS, PRIZE -> BottomSheetType.NUMERIC_TEXT BUY_IN, TIPS -> BottomSheetType.SUM BLINDS -> BottomSheetType.DOUBLE_EDIT_TEXT GAME -> BottomSheetType.LIST_GAME @@ -151,10 +191,15 @@ enum class SessionRow : RowRepresentable { val sb: String? by map val bb: String? by map arrayListOf( - RowRepresentableEditDescriptor(sb, R.string.smallblind, InputType.TYPE_CLASS_NUMBER - or InputType.TYPE_NUMBER_FLAG_DECIMAL), - RowRepresentableEditDescriptor(bb, R.string.bigblind, InputType.TYPE_CLASS_NUMBER - or InputType.TYPE_NUMBER_FLAG_DECIMAL)) + RowRepresentableEditDescriptor( + sb, R.string.smallblind, InputType.TYPE_CLASS_NUMBER + or InputType.TYPE_NUMBER_FLAG_DECIMAL + ), + RowRepresentableEditDescriptor( + bb, R.string.bigblind, InputType.TYPE_CLASS_NUMBER + or InputType.TYPE_NUMBER_FLAG_DECIMAL + ) + ) } BUY_IN -> { val bb: Double? by map @@ -162,11 +207,11 @@ enum class SessionRow : RowRepresentable { val ratedBuyin: Double? by map val data = arrayListOf() if (bb != null) { - data.add(RowRepresentableEditDescriptor(100.0 * (bb?: 0.0))) - data.add(RowRepresentableEditDescriptor(200.0 * (bb?: 0.0))) + data.add(RowRepresentableEditDescriptor(100.0 * (bb ?: 0.0))) + data.add(RowRepresentableEditDescriptor(200.0 * (bb ?: 0.0))) } else if (fee != null) { - data.add(RowRepresentableEditDescriptor((fee?: 0.0) * 1.0)) - data.add(RowRepresentableEditDescriptor((fee?: 0.0) * 2.0)) + data.add(RowRepresentableEditDescriptor((fee ?: 0.0) * 1.0)) + data.add(RowRepresentableEditDescriptor((fee ?: 0.0) * 2.0)) } else { data.add(RowRepresentableEditDescriptor(0)) data.add(RowRepresentableEditDescriptor(0)) @@ -186,17 +231,18 @@ enum class SessionRow : RowRepresentable { data } CASHED_OUT, PRIZE, NET_RESULT -> { - val defaultValue: String? by map + val defaultValue: Double? by map arrayListOf( - RowRepresentableEditDescriptor( - defaultValue, - inputType = InputType.TYPE_CLASS_NUMBER - or InputType.TYPE_NUMBER_FLAG_DECIMAL - or InputType.TYPE_NUMBER_FLAG_SIGNED - )) + RowRepresentableEditDescriptor( + defaultValue, + inputType = InputType.TYPE_CLASS_NUMBER + or InputType.TYPE_NUMBER_FLAG_DECIMAL + or InputType.TYPE_NUMBER_FLAG_SIGNED + ) + ) } COMMENT -> { - val defaultValue : String? by map + val defaultValue: String? by map arrayListOf(RowRepresentableEditDescriptor(defaultValue, R.string.comment)) } BREAK_TIME -> { @@ -207,22 +253,23 @@ enum class SessionRow : RowRepresentable { ) } GAME -> { - val limit : Int? by map - val defaultValue : Any? by map - val data : RealmResults<*>? by map + val limit: Int? by map + val defaultValue: Any? by map + val data: RealmResults<*>? by map arrayListOf( RowRepresentableEditDescriptor(limit), - RowRepresentableEditDescriptor(defaultValue, data = data)) + RowRepresentableEditDescriptor(defaultValue, data = data) + ) } INITIAL_BUY_IN -> { - val defaultValue : Double? by map + val defaultValue: Double? by map arrayListOf( RowRepresentableEditDescriptor(defaultValue?.round(), inputType = InputType.TYPE_CLASS_NUMBER) ) } BANKROLL, LOCATION, TOURNAMENT_FEATURE, TOURNAMENT_NAME -> { - val defaultValue : Any? by map - val data : RealmResults<*>? by map + val defaultValue: Any? by map + val data: RealmResults<*>? by map arrayListOf( RowRepresentableEditDescriptor(defaultValue, data = data) ) @@ -237,7 +284,7 @@ enum class SessionRow : RowRepresentable { ) } POSITION -> { - val defaultValue : Int? by map + val defaultValue: Int? by map arrayListOf( RowRepresentableEditDescriptor( defaultValue, @@ -246,7 +293,7 @@ enum class SessionRow : RowRepresentable { ) } TABLE_SIZE -> { - val defaultValue : Int? by map + val defaultValue: Int? by map arrayListOf(RowRepresentableEditDescriptor(defaultValue)) } TIPS -> { @@ -256,19 +303,20 @@ enum class SessionRow : RowRepresentable { // Disable the buttons with value = 0, add current value & set the 2 edit texts arrayListOf( - RowRepresentableEditDescriptor(sb?: 0.0), - RowRepresentableEditDescriptor(bb?: 0.0), - RowRepresentableEditDescriptor(tips?: 0.0), + RowRepresentableEditDescriptor(sb ?: 0.0), + RowRepresentableEditDescriptor(bb ?: 0.0), + RowRepresentableEditDescriptor(tips ?: 0.0), RowRepresentableEditDescriptor("", inputType = InputType.TYPE_CLASS_NUMBER), RowRepresentableEditDescriptor("", inputType = InputType.TYPE_CLASS_NUMBER) ) } TOURNAMENT_TYPE -> { - val defaultValue : Any? by map + val defaultValue: Any? by map arrayListOf( - RowRepresentableEditDescriptor(defaultValue, staticData = TournamentType.values().map { - it - })) + RowRepresentableEditDescriptor(defaultValue, staticData = TournamentType.values().map { + it + }) + ) } else -> null } From 74d92ad622b6cbfbc01119580da703bdbdc79cc5 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 15 Apr 2019 18:03:06 +0200 Subject: [PATCH 011/197] bumping to versionCode 14 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c7169b95..db66d90c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 13 + versionCode 14 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From 307e6d2b745378c8df14b6f17e784a405dd9369f Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 15 Apr 2019 19:24:13 +0200 Subject: [PATCH 012/197] Fix crashes --- .../android/ui/fragment/BankrollDataFragment.kt | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt index 14283c47..c05569ff 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt @@ -88,18 +88,15 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS return when (row) { SimpleRow.NAME -> if (bankroll.name.isNotEmpty()) bankroll.name else NULL_TEXT BankrollRow.CURRENCY -> { - bankroll.currency?.let { - Currency.getInstance(it.code).currencyCode + bankroll.currency?.code?.let { code -> + Currency.getInstance(code).currencyCode } ?: run { NULL_TEXT } } BankrollRow.RATE -> { - this.bankroll.currency?.rate?.let { rate -> - CurrencyUtils.getCurrencyRateFormatter().format(rate) - } ?: run { - CurrencyUtils.getCurrencyRateFormatter().format(1.0) - } + val rate = this.bankroll.currency?.rate ?: 1.0 + CurrencyUtils.getCurrencyRateFormatter().format(rate) } else -> super.stringForRow(row) } From f5b9190583d1aadaefe800b740fd7c72cd1db4a8 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 15 Apr 2019 19:40:18 +0200 Subject: [PATCH 013/197] Fixes more crashes --- app/build.gradle | 2 +- .../pokeranalytics/android/model/realm/Session.kt | 14 ++++++++++++-- .../bottomsheet/BottomSheetNumericTextFragment.kt | 10 +++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index db66d90c..6bf19dc6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 14 + versionCode 15 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 0244b20e..8d755280 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -802,10 +802,20 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } SessionRow.INITIAL_BUY_IN -> tournamentEntryFee = if (value == null) null else (value as String).toDouble() SessionRow.LOCATION -> location = value as Location? - SessionRow.PLAYERS -> tournamentNumberOfPlayers = if (value != null) (value as String).toInt() else null + SessionRow.PLAYERS -> { + if (value is Double) { + this.tournamentNumberOfPlayers = value.toInt() + } else { + this.tournamentNumberOfPlayers = null + } + } SessionRow.POSITION -> { val localResult = if (result != null) result as Result else realm.createObject(Result::class.java) - localResult.tournamentFinalPosition = if (value == null) null else (value as String).toInt() + if (value is Double) { + localResult.tournamentFinalPosition = value.toInt() + } else { + localResult.tournamentFinalPosition = null + } result = localResult } SessionRow.START_DATE -> if (value is Date) { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt index 8e953d6c..da9486d5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt @@ -61,9 +61,13 @@ class BottomSheetNumericTextFragment : BottomSheetFragment() { } data[0].defaultValue?.let { - val formatter = NumberFormat.getNumberInstance() - formatter.isGroupingUsed = false - editText1.setText(formatter.format(it)) + if (it is Double || it is Long) { + val formatter = NumberFormat.getNumberInstance() + formatter.isGroupingUsed = false + editText1.setText(formatter.format(it)) + } else { + editText1.setText(it.toString()) + } } editText1.setOnEditorActionListener { _, actionId, _ -> From fba9968a108912dec129eef5d0a340e85dbd8236 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 15 Apr 2019 19:47:19 +0200 Subject: [PATCH 014/197] Fixing crash and bug --- .../pokeranalytics/android/model/realm/Session.kt | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 8d755280..73842543 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -800,7 +800,9 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat game = null } } - SessionRow.INITIAL_BUY_IN -> tournamentEntryFee = if (value == null) null else (value as String).toDouble() + SessionRow.INITIAL_BUY_IN -> { + this.tournamentEntryFee = (value as Double?) + } SessionRow.LOCATION -> location = value as Location? SessionRow.PLAYERS -> { if (value is Double) { @@ -829,9 +831,14 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } SessionRow.TOURNAMENT_NAME -> tournamentName = value as TournamentName? SessionRow.TOURNAMENT_TYPE -> tournamentType = value as Int? - SessionRow.TOURNAMENT_FEATURE -> value?.let { - tournamentFeatures = RealmList() - tournamentFeatures.addAll((it as ArrayList)) + SessionRow.TOURNAMENT_FEATURE -> { + + value?.let { + tournamentFeatures = RealmList() + tournamentFeatures.addAll((it as ArrayList)) + } ?: run { + tournamentFeatures.removeAll(this.tournamentFeatures) + } } } } From f4a749fbb8137566e374fba0e8762bd23514d037 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 16 Apr 2019 09:23:54 +0200 Subject: [PATCH 015/197] bumping to versionCode 16 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 6bf19dc6..4c62fa11 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 15 + versionCode 16 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From b591ba977c1692040122244778d21f76772e3d54 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 16 Apr 2019 10:57:54 +0200 Subject: [PATCH 016/197] Fixes crash with thousands + improved format --- .../net/pokeranalytics/android/model/realm/Bankroll.kt | 6 +----- .../android/ui/fragment/BankrollDataFragment.kt | 7 +++---- .../pokeranalytics/android/ui/fragment/SettingsFragment.kt | 5 ++++- .../bottomsheet/BottomSheetNumericTextFragment.kt | 1 + .../android/ui/view/rowrepresentable/BankrollRow.kt | 4 ++-- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt index c5a3df93..b05eb7e2 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt @@ -89,11 +89,7 @@ open class Bankroll() : RealmObject(), NameManageable, StaticRowRepresentableDat this.currency?.code = value as String? } BankrollRow.RATE -> { - value?.let { rate -> - this.currency?.rate = (rate as String).toDouble() - } ?: run { - this.currency?.rate = null - } + this.currency?.rate = value as Double? } } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt index c05569ff..675e198f 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt @@ -114,9 +114,8 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS return when (row) { SimpleRow.NAME -> row.editingDescriptors(mapOf("defaultValue" to this.bankroll.name)) BankrollRow.RATE -> { - val rate = this.bankroll.currency?.rate ?: 1.0 - val rateFormatted = CurrencyUtils.getCurrencyRateFormatter().format(rate) - row.editingDescriptors(mapOf("defaultValue" to rateFormatted)) + val rate = this.bankroll.currency?.rate + row.editingDescriptors(mapOf("defaultValue" to rate)) } else -> null } @@ -205,7 +204,7 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS override fun onResponse(call: Call>, response: Response>) { response.body()?.let { it[currenciesConverterValue]?.value?.let { rate -> - onRowValueChanged(rate.toString(), BankrollRow.RATE) + onRowValueChanged(rate, BankrollRow.RATE) } } 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 8b6a3802..db953583 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 @@ -56,7 +56,10 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta override fun stringForRow(row: RowRepresentable): String { return when (row) { SettingRow.VERSION -> BuildConfig.VERSION_NAME + if (BuildConfig.DEBUG) " (${BuildConfig.VERSION_CODE}) DEBUG" else "" - SettingRow.CURRENCY -> Currency.getInstance(Preferences.getCurrencyLocale(this.parentActivity)).symbol + SettingRow.CURRENCY -> { + val locale = Preferences.getCurrencyLocale(this.parentActivity) + Currency.getInstance(locale).symbol + } else -> "" } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt index da9486d5..da8f8510 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt @@ -63,6 +63,7 @@ class BottomSheetNumericTextFragment : BottomSheetFragment() { data[0].defaultValue?.let { if (it is Double || it is Long) { val formatter = NumberFormat.getNumberInstance() + formatter.maximumFractionDigits = 6 formatter.isGroupingUsed = false editText1.setText(formatter.format(it)) } else { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/BankrollRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/BankrollRow.kt index df724f8e..f5cfdc6a 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/BankrollRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/BankrollRow.kt @@ -40,14 +40,14 @@ enum class BankrollRow : RowRepresentable, DefaultEditDataSource { return when (this) { LIVE -> BottomSheetType.NONE CURRENCY -> BottomSheetType.NONE - RATE -> BottomSheetType.EDIT_TEXT + RATE -> BottomSheetType.NUMERIC_TEXT REFRESH_RATE -> BottomSheetType.NONE } } override fun editingDescriptors(map: Map): ArrayList? { return when (this) { - BankrollRow.RATE -> { + RATE -> { val defaultValue : Any? by map arrayListOf( RowRepresentableEditDescriptor(defaultValue, R.string.rate, InputType.TYPE_CLASS_NUMBER From 4f1ed02a91847d699e4ef6a631f0c1fa6e87a3ae Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 16 Apr 2019 11:17:44 +0200 Subject: [PATCH 017/197] Fixes crash when setting break and refresh UI --- .../java/net/pokeranalytics/android/model/realm/Session.kt | 2 +- .../net/pokeranalytics/android/ui/fragment/SessionFragment.kt | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 73842543..8c06e858 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -756,7 +756,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat cgBigBlind = null } SessionRow.BREAK_TIME -> { - this.breakDuration = if (value != null) (value as String).toLong() * 60 * 1000 else 0 + this.breakDuration = (value as Double? ?: 0.0).toLong() * 60 * 1000 } SessionRow.BUY_IN -> { val localResult = if (this.result != null) this.result as Result else realm.createObject(Result::class.java) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt index a0f6893a..627ba629 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt @@ -117,8 +117,7 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate { sessionAdapter.refreshRow(row) when (row) { SessionRow.CASHED_OUT, SessionRow.PRIZE, SessionRow.NET_RESULT, SessionRow.BUY_IN, SessionRow.TIPS, - SessionRow.START_DATE, SessionRow.END_DATE, SessionRow.BANKROLL -> updateSessionUI() - SessionRow.BREAK_TIME -> this.sessionAdapter.notifyDataSetChanged() + SessionRow.START_DATE, SessionRow.END_DATE, SessionRow.BANKROLL, SessionRow.BREAK_TIME -> updateSessionUI() } } From cf0991a467c4cdaad6913bbe7be1146587e0dc9a Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 16 Apr 2019 11:29:26 +0200 Subject: [PATCH 018/197] Patch session set break times --- .../android/PokerAnalyticsApplication.kt | 3 ++ .../android/model/migrations/Patcher.kt | 28 +++++++++++++++++++ .../android/model/realm/SessionSet.kt | 1 + 3 files changed, 32 insertions(+) create mode 100644 app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index 60b02421..7cbb59df 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -9,6 +9,7 @@ import io.realm.RealmConfiguration import io.realm.kotlin.where import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch +import net.pokeranalytics.android.model.migrations.Patcher import net.pokeranalytics.android.model.migrations.PokerAnalyticsMigration import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.utils.Seed @@ -50,6 +51,8 @@ class PokerAnalyticsApplication : Application() { if (BuildConfig.DEBUG) { // this.createFakeSessions() } + + Patcher.patchBreaks() } /** diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt new file mode 100644 index 00000000..498cf6d2 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt @@ -0,0 +1,28 @@ +package net.pokeranalytics.android.model.migrations + +import io.realm.Realm +import net.pokeranalytics.android.model.realm.SessionSet + +class Patcher { + + companion object { + + fun patchBreaks() { + + val realm = Realm.getDefaultInstance() + val sets = realm.where(SessionSet::class.java).findAll() + + realm.executeTransaction { + sets.forEach { + it.computeStats() + } + + } + realm.close() + + } + + } + + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt index 9774e1b7..2e5cd71b 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt @@ -61,6 +61,7 @@ open class SessionSet() : RealmObject(), Timed, Filterable { this.ratedNet = this.sessions?.sumByDouble { it.computableResult?.ratedNet ?: 0.0 } ?: 0.0 this.estimatedHands = this.sessions?.sumByDouble { it.estimatedHands } ?: 0.0 this.bbNet = this.sessions?.sumByDouble { it.bbNet } ?: 0.0 + this.breakDuration = this.sessions?.max("breakDuration")?.toLong() ?: 0L } /** From 21e8f64b95ce89437d0bae0b6b961f8f27a86666 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Tue, 16 Apr 2019 11:29:57 +0200 Subject: [PATCH 019/197] fix issue with currency --- .../android/ui/fragment/CurrenciesFragment.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt index ba01d35f..4a53d724 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt @@ -46,6 +46,14 @@ class CurrenciesFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataS private val availableCurrencies = this.systemCurrencies.filter { !mostUsedCurrencyCodes.contains(it.currencyCode) + }.filter { + Locale.getAvailableLocales().filter {locale -> + try { + Currency.getInstance(locale).currencyCode == it.currencyCode + } catch (e: Exception) { + false + } + }.isNotEmpty() }.sortedBy { it.displayName }.map { From cef1a410738f30d40f251c20ee7eeb0a3e198ad8 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 16 Apr 2019 11:33:02 +0200 Subject: [PATCH 020/197] bumping versionCode to 17 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 4c62fa11..62def270 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 16 + versionCode 17 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From 4b8c08299606333e963abfd83f6b49f2c9f7729b Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Tue, 16 Apr 2019 12:24:28 +0200 Subject: [PATCH 021/197] fix issue with currency --- .../java/net/pokeranalytics/android/model/realm/Session.kt | 7 ++++--- .../android/ui/fragment/CurrenciesFragment.kt | 3 ++- .../pokeranalytics/android/ui/fragment/SettingsFragment.kt | 2 +- .../net/pokeranalytics/android/ui/view/SessionRowView.kt | 2 +- .../android/ui/view/rowrepresentable/FilterSectionRow.kt | 5 ----- .../android/util/extensions/NumbersExtension.kt | 3 ++- 6 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 8c06e858..9994fe98 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -37,6 +37,7 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRowRepresent import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow import net.pokeranalytics.android.util.CurrencyUtils import net.pokeranalytics.android.util.NULL_TEXT +import net.pokeranalytics.android.util.Preferences import net.pokeranalytics.android.util.extensions.* import java.util.* import java.util.Currency @@ -485,9 +486,9 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat /** * Return the formatted blinds */ - fun getBlinds(): String { + fun getBlinds(context: Context): String { val currencyCode = bankroll?.currency?.code ?: CurrencyUtils.getLocaleCurrency().currencyCode - val currencySymbol = Currency.getInstance(currencyCode).symbol + val currencySymbol = Currency.getInstance(currencyCode).getSymbol(Preferences.getCurrencyLocale(context)) return if (cgSmallBlind == null) NULL_TEXT else "$currencySymbol ${cgSmallBlind?.formatted()}/${cgBigBlind?.round()}" } @@ -624,7 +625,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat override fun stringForRow(row: RowRepresentable, context: Context): String { return when (row) { SessionRow.BANKROLL -> bankroll?.name ?: NULL_TEXT - SessionRow.BLINDS -> getBlinds() + SessionRow.BLINDS -> getBlinds(context) SessionRow.BREAK_TIME -> if (this.breakDuration > 0.0) this.breakDuration.toMinutes() else NULL_TEXT SessionRow.BUY_IN -> this.result?.buyin?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT SessionRow.CASHED_OUT, SessionRow.PRIZE -> this.result?.cashout?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt index 4a53d724..1ff8fee5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt @@ -17,6 +17,7 @@ import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRowRepresentable +import net.pokeranalytics.android.util.Preferences import java.util.* class CurrenciesFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { @@ -68,7 +69,7 @@ class CurrenciesFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataS } var currencyCode: String = currency.currencyCode - var currencySymbole: String = currency.getSymbol(Locale.getDefault()) + var currencySymbole: String = currency.getSymbol(Preferences.currencyLocale) var currencyCodeAndSymbol: String = "${this.currencyCode} (${this.currencySymbole})" override val viewType: Int = RowViewType.TITLE_VALUE.ordinal 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 db953583..70a22ecc 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 @@ -58,7 +58,7 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta SettingRow.VERSION -> BuildConfig.VERSION_NAME + if (BuildConfig.DEBUG) " (${BuildConfig.VERSION_CODE}) DEBUG" else "" SettingRow.CURRENCY -> { val locale = Preferences.getCurrencyLocale(this.parentActivity) - Currency.getInstance(locale).symbol + Currency.getInstance(locale).getSymbol(locale) } else -> "" } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt index 6cef22f9..9a0c441c 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt @@ -85,7 +85,7 @@ class SessionRowView : FrameLayout { } } else { if (session.cgSmallBlind != null && session.cgBigBlind != null) { - parameters.add(session.getBlinds()) + parameters.add(session.getBlinds(context)) } session.game?.let { parameters.add(session.getFormattedGame()) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt index 1c2006be..c198a5f4 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt @@ -157,15 +157,10 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable { val distinctBlinds: ArrayList = ArrayList() val blindsHashMap: ArrayList = ArrayList() sessions.forEach { - if (!blindsHashMap.contains(it.getBlinds())) { - blindsHashMap.add(it.getBlinds()) - distinctBlinds.add(it) - } } distinctBlinds.forEach { session -> blinds.add(Blind(session.cgSmallBlind, session.cgBigBlind, session.bankroll?.currency?.code)) - session.getBlinds() } realm.close() diff --git a/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt b/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt index 88330925..26c9bfc6 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt @@ -2,6 +2,7 @@ package net.pokeranalytics.android.util.extensions import android.content.Context import net.pokeranalytics.android.R +import net.pokeranalytics.android.util.Preferences import java.text.DecimalFormat import java.text.NumberFormat import java.util.* @@ -23,7 +24,7 @@ fun Double.formatted(): String { fun Double.toCurrency(currency: Currency? = null): String { - val currencyFormatter = NumberFormat.getCurrencyInstance() + val currencyFormatter = NumberFormat.getCurrencyInstance(Preferences.currencyLocale) currency?.let { currencyFormatter.currency = currency } From ab1f5ce4df403391c0de4514c089b63578044568 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 19 Apr 2019 16:56:05 +0200 Subject: [PATCH 022/197] Remove warning --- app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt index 01b652b1..2b8c7387 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt @@ -150,7 +150,7 @@ enum class Stat(var underlyingClass: Class? = null) : RowRepresentabl fun cumulativeLabelResId(context: Context) : String { val resId = when (this) { - AVERAGE, AVERAGE_DURATION, NETRESULT, NET_BB_PER_100_HANDS, + AVERAGE, AVERAGE_DURATION, NET_BB_PER_100_HANDS, HOURLY_RATE_BB, AVERAGE_NET_BB, ROI, WIN_RATIO, HOURLY_RATE -> R.string.average NETRESULT, DURATION -> R.string.total STANDARD_DEVIATION -> R.string.net_result From 9dac04fd95856c23a030ad4f7c516b7a4f8b2b71 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 24 Apr 2019 17:35:21 +0200 Subject: [PATCH 023/197] Hide filter button in Feed & Stats --- .../net/pokeranalytics/android/ui/activity/HomeActivity.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt index 610a948c..c8512d55 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt @@ -77,7 +77,7 @@ class HomeActivity : PokerAnalyticsActivity() { menuInflater.inflate(R.menu.toolbar_home, menu) this.homeMenu = menu //TODO: Change queryWith button visibility - homeMenu?.findItem(R.id.filter)?.isVisible = true + homeMenu?.findItem(R.id.filter)?.isVisible = false return super.onCreateOptionsMenu(menu) } @@ -168,11 +168,11 @@ class HomeActivity : PokerAnalyticsActivity() { 0 -> { toolbar.title = getString(R.string.feed) - homeMenu?.findItem(R.id.filter)?.isVisible = true + homeMenu?.findItem(R.id.filter)?.isVisible = false } 1 -> { toolbar.title = getString(R.string.stats) - homeMenu?.findItem(R.id.filter)?.isVisible = true + homeMenu?.findItem(R.id.filter)?.isVisible = false } 2 -> { toolbar.title = getString(R.string.calendar) From c2588282edd3ac7803adb71aa4b4757a729a2ffd Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 24 Apr 2019 17:50:18 +0200 Subject: [PATCH 024/197] Remove More tab --- .../android/ui/activity/HomeActivity.kt | 7 ++- .../android/ui/adapter/HomePagerAdapter.kt | 4 +- .../android/ui/fragment/SettingsFragment.kt | 6 +- app/src/main/res/layout/fragment_settings.xml | 56 +++++++++---------- app/src/main/res/menu/navigation_home.xml | 11 +++- 5 files changed, 46 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt index c8512d55..f4bccafc 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt @@ -56,9 +56,12 @@ class HomeActivity : PokerAnalyticsActivity() { R.id.navigation_reports -> { displayFragment(3) } - R.id.navigation_more -> { + R.id.navigation_settings -> { displayFragment(4) } +// R.id.navigation_more -> { +// displayFragment(4) +// } } return@OnNavigationItemSelectedListener true } @@ -183,7 +186,7 @@ class HomeActivity : PokerAnalyticsActivity() { homeMenu?.findItem(R.id.filter)?.isVisible = false } 4 -> { - toolbar.title = getString(R.string.more) + toolbar.title = getString(R.string.services) //getString(R.string.more) homeMenu?.findItem(R.id.filter)?.isVisible = false } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/HomePagerAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/HomePagerAdapter.kt index f749a4db..d9f0c784 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/HomePagerAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/HomePagerAdapter.kt @@ -21,7 +21,7 @@ class HomePagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAda 1 -> StatisticsFragment.newInstance() 2 -> CalendarFragment.newInstance() 3 -> ReportsFragment.newInstance() - 4 -> MoreFragment.newInstance() + 4 -> SettingsFragment.newInstance() // MoreFragment.newInstance() else -> HistoryFragment.newInstance() } } @@ -47,7 +47,7 @@ class HomePagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAda StatisticsFragment::class.java -> 1 CalendarFragment::class.java -> 2 ReportsFragment::class.java -> 3 - MoreFragment::class.java -> 4 + SettingsFragment::class.java -> 4 else -> -1 } } 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 b396874f..d4cbd1b5 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 @@ -127,9 +127,9 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta parentActivity = activity as PokerAnalyticsActivity - parentActivity.setSupportActionBar(toolbar) - parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true) - setHasOptionsMenu(true) +// parentActivity.setSupportActionBar(toolbar) +// parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true) +// setHasOptionsMenu(true) val viewManager = LinearLayoutManager(requireContext()) settingsAdapterRow = RowRepresentableAdapter( diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index 8542d548..e1d3e396 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -25,33 +25,33 @@ - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/navigation_home.xml b/app/src/main/res/menu/navigation_home.xml index 6ac0f33b..1ec55274 100644 --- a/app/src/main/res/menu/navigation_home.xml +++ b/app/src/main/res/menu/navigation_home.xml @@ -40,8 +40,13 @@ android:title="@string/reports" /> + android:id="@+id/navigation_settings" + android:icon="@drawable/ic_outline_settings" + android:title="@string/services" /> + + + + + From 6801057919a915c19b89600acfd256417b7020b3 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Wed, 24 Apr 2019 17:33:26 +0200 Subject: [PATCH 025/197] update realm migration for FilterCondition --- .../model/migrations/PokerAnalyticsMigration.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index 4a1b109b..608792bb 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -59,9 +59,13 @@ class PokerAnalyticsMigration : RealmMigration { schema.get("FilterCondition")?.let { it.removeField("blindValues") - it.addField("operator", Int::class.java).setNullable("operator", true) - it.addField("intValue", Int::class.java).setNullable("intValue", true) - it.addField("doubleValue", Double::class.java).setNullable("intValue", true) + it.removeField("numericValues") + + it.addField("operator", Integer::class.java).setNullable("operator", true) + it.addField("intValue", Integer::class.java).setNullable("intValue", true) + it.addRealmListField("intValues", Integer::class.java).setNullable("intValues", true) + it.addField("doubleValue", Double::class.java).setNullable("doubleValue", true) + it.addRealmListField("doubleValues", Double::class.java).setNullable("doubleValues", true) it.addField("stringValue", String::class.java).setNullable("stringValue", true) } From 244151f2cb42f5b0171192739cab0ddd807a4efc Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Wed, 24 Apr 2019 17:45:10 +0200 Subject: [PATCH 026/197] update realm migration for FilterCondition --- .../model/migrations/PokerAnalyticsMigration.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index 608792bb..819d357f 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -61,12 +61,12 @@ class PokerAnalyticsMigration : RealmMigration { it.removeField("blindValues") it.removeField("numericValues") - it.addField("operator", Integer::class.java).setNullable("operator", true) - it.addField("intValue", Integer::class.java).setNullable("intValue", true) - it.addRealmListField("intValues", Integer::class.java).setNullable("intValues", true) - it.addField("doubleValue", Double::class.java).setNullable("doubleValue", true) - it.addRealmListField("doubleValues", Double::class.java).setNullable("doubleValues", true) - it.addField("stringValue", String::class.java).setNullable("stringValue", true) + it.addField("operator", Integer::class.java) + it.addField("intValue", Integer::class.java) + it.addRealmListField("intValues", Integer::class.java) + it.addField("doubleValue", Double::class.java) + it.addRealmListField("doubleValues", Double::class.java) + it.addField("stringValue", String::class.java) } schema.get("ComputableResult")?.let { From d95371061f47bfa18de1a5d9d0aecf5ad5a25de0 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Wed, 24 Apr 2019 17:56:12 +0200 Subject: [PATCH 027/197] update realm migration for FilterCondition --- .../android/model/migrations/PokerAnalyticsMigration.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index 819d357f..7c3cfeec 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -64,8 +64,8 @@ class PokerAnalyticsMigration : RealmMigration { it.addField("operator", Integer::class.java) it.addField("intValue", Integer::class.java) it.addRealmListField("intValues", Integer::class.java) - it.addField("doubleValue", Double::class.java) - it.addRealmListField("doubleValues", Double::class.java) + it.addField("doubleValue", Double::class.java).setNullable("doubleValue", true) + it.addRealmListField("doubleValues", Double::class.java).setNullable("doubleValue", true) it.addField("stringValue", String::class.java) } @@ -74,7 +74,7 @@ class PokerAnalyticsMigration : RealmMigration { } schema.get("Bankroll")?.let { - it.addField("initialValue", Double::class.java).setRequired("initialValue", true) + it.addField("initialValue", Double::class.java) } currentVersion++ From e76a30acb622d9bff6a1f045e8849c3d87414ce4 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Wed, 24 Apr 2019 18:08:40 +0200 Subject: [PATCH 028/197] update realm migration for FilterCondition --- .../android/model/migrations/PokerAnalyticsMigration.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index 7c3cfeec..32d9436e 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -65,7 +65,7 @@ class PokerAnalyticsMigration : RealmMigration { it.addField("intValue", Integer::class.java) it.addRealmListField("intValues", Integer::class.java) it.addField("doubleValue", Double::class.java).setNullable("doubleValue", true) - it.addRealmListField("doubleValues", Double::class.java).setNullable("doubleValue", true) + it.addRealmListField("doubleValues", Double::class.java) it.addField("stringValue", String::class.java) } From bd7b4b22dc5db4ac459dd15f61e83f10d7727df7 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Wed, 24 Apr 2019 18:19:54 +0200 Subject: [PATCH 029/197] update realm migration for FilterCondition --- .../model/migrations/PokerAnalyticsMigration.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index 32d9436e..81fb9afe 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -4,6 +4,9 @@ import io.realm.DynamicRealm import io.realm.RealmMigration import timber.log.Timber import java.util.* +import io.realm.RealmObjectSchema + + class PokerAnalyticsMigration : RealmMigration { @@ -39,7 +42,6 @@ class PokerAnalyticsMigration : RealmMigration { schema.rename("FilterElement", "FilterCondition") schema.get("Filter")?.let { it.renameField("filterElements", "filterConditions") - it.removeField("entityType") } schema.get("SessionSet")?.let { it.addField("id", String::class.java).setRequired("id", true) @@ -53,6 +55,10 @@ class PokerAnalyticsMigration : RealmMigration { Timber.d("*** Running migration ${currentVersion + 1}") schema.rename("Report", "ReportSetup") + schema.get("Filter")?.let { + it.removeField("entityType") + } + schema.get("Session")?.let { it.addField("blinds", String::class.java) } @@ -66,6 +72,9 @@ class PokerAnalyticsMigration : RealmMigration { it.addRealmListField("intValues", Integer::class.java) it.addField("doubleValue", Double::class.java).setNullable("doubleValue", true) it.addRealmListField("doubleValues", Double::class.java) + if(it.isRequired("doubleValues")) { + it.setRequired("doubleValues", false) + } it.addField("stringValue", String::class.java) } From 30b49bff31bcb0900285e3e96b94bd75e7eeffc6 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 24 Apr 2019 18:33:23 +0200 Subject: [PATCH 030/197] look & feel for new beta --- .../java/net/pokeranalytics/android/ui/activity/HomeActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt index f4bccafc..ed6a115e 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt @@ -35,7 +35,7 @@ class HomeActivity : PokerAnalyticsActivity() { //CLEAN /* R.id.navigation_history -> { - displayFragment(0) + displayFragment(0)§ } R.id.navigation_stats -> { displayFragment(1) From 15928823c543d601eb8d1fc7ae1e21daabff8349 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 24 Apr 2019 19:02:27 +0200 Subject: [PATCH 031/197] Fixes various bugs --- .../pokeranalytics/android/calculus/Calculator.kt | 8 ++------ .../net/pokeranalytics/android/calculus/Stat.kt | 13 ++++++++++++- .../android/ui/fragment/GraphFragment.kt | 7 +++++-- .../android/ui/fragment/ReportsFragment.kt | 2 +- .../android/ui/fragment/StatisticDetailsFragment.kt | 12 ++++++++++++ .../android/ui/fragment/StatisticsFragment.kt | 9 ++++++++- .../android/ui/view/SessionRowView.kt | 6 ++++-- app/src/main/res/values/strings.xml | 2 +- 8 files changed, 45 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt index 1347d7f4..9bcf98fc 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt @@ -120,12 +120,8 @@ class Calculator { return when (aggregationType) { AggregationType.SESSION, AggregationType.DURATION -> this.computeGroups(realm, listOf(group), options) - AggregationType.MONTH -> { - val criteria: List = listOf(Criteria.Years, Criteria.MonthsOfYear) - this.computeStatsWithComparators(realm, criteria, group.conditions, options) - } - AggregationType.YEAR -> { - val criteria: List = listOf(Criteria.Years) + AggregationType.MONTH, AggregationType.YEAR -> { + val criteria: List = aggregationType.criterias this.computeStatsWithComparators(realm, criteria, group.conditions, options) } } diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt index e8fc3c68..491aa7d7 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt @@ -3,6 +3,7 @@ package net.pokeranalytics.android.calculus import android.content.Context import net.pokeranalytics.android.R import net.pokeranalytics.android.exceptions.FormattingException +import net.pokeranalytics.android.model.Criteria import net.pokeranalytics.android.model.interfaces.Timed import net.pokeranalytics.android.ui.graph.AxisFormatting import net.pokeranalytics.android.ui.view.RowRepresentable @@ -46,6 +47,15 @@ enum class AggregationType { } } + val criterias: List + get() { + return when (this) { + MONTH -> listOf(Criteria.Years, Criteria.MonthsOfYear) + YEAR -> listOf(Criteria.Years) + else -> listOf() + } + } + } /** @@ -233,7 +243,8 @@ enum class Stat : RowRepresentable { val hasEvolutionGraph: Boolean get() { return when (this) { - HOURLY_DURATION, AVERAGE_HOURLY_DURATION -> false + HOURLY_DURATION, AVERAGE_HOURLY_DURATION, + STANDARD_DEVIATION, STANDARD_DEVIATION_HOURLY, STANDARD_DEVIATION_BB_PER_100_HANDS -> false else -> true } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt index 0ae4886d..783da46a 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt @@ -132,9 +132,12 @@ class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener { this.chartView = lineChart dataSets.firstOrNull()?.let { + this.legendView.prepareWithStat(this.stat, it.entryCount, this.style) - lastEntry = it.getEntryForIndex(it.entryCount - 1) - groupName = it.label + if (it.entryCount > 0) { + lastEntry = it.getEntryForIndex(it.entryCount - 1) + groupName = it.label + } } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt index 8e35f4b4..488c76ec 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt @@ -108,7 +108,7 @@ class ReportsFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSour private fun launchComputation(criteria: List, reportName: String) { if (criteria.combined().size < 2) { - Toast.makeText(context, R.string.less_then_2_values_for_comparison, Toast.LENGTH_LONG).show() + Toast.makeText(context, R.string.less_then_2_values_for_display, Toast.LENGTH_LONG).show() return } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt index 3ed90ebe..c3602d3d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.core.view.isVisible import com.github.mikephil.charting.data.BarDataSet import com.github.mikephil.charting.data.LineDataSet @@ -16,6 +17,7 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.* +import net.pokeranalytics.android.model.combined import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.extensions.ChipGroupExtension import net.pokeranalytics.android.ui.extensions.hideWithAnimation @@ -107,6 +109,16 @@ class StatisticDetailsFragment : PokerAnalyticsFragment() { super.onCheckedChanged(group, checkedId) val aggregationType = aggregationTypes[checkedId] + when (aggregationType) { + AggregationType.MONTH, AggregationType.YEAR -> { + val queryConditions = aggregationType.criterias.combined() + if (queryConditions.size < 2) { + Toast.makeText(context, R.string.less_then_2_values_for_display, Toast.LENGTH_LONG).show() + return + } + } + } + reports[aggregationType]?.let { report -> setGraphData(report, aggregationType) } ?: run { 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 5fedf62d..fd147bb0 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 @@ -139,7 +139,14 @@ class StatisticsFragment : TableReportFragment() { Timber.d(">>>>> Start computations...") - return Calculator.computeGroups(realm, listOf(allSessionGroup, cgSessionGroup, tSessionGroup), Calculator.Options()) + val options = Calculator.Options() + var computedStats = mutableListOf() + computedStats.addAll(allStats) + computedStats.addAll(cgStats) + computedStats.addAll(tStats) + options.displayedStats = computedStats + + return Calculator.computeGroups(realm, listOf(allSessionGroup, cgSessionGroup, tSessionGroup), options) } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt index 9920cbee..fc9b1c39 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt @@ -58,9 +58,11 @@ class SessionRowView : FrameLayout { */ fun setData(session: Session) { + val date = session.startDate ?: session.creationDate + // Date - rowHistorySession.dateDay.text = session.creationDate.getShortDayName() - rowHistorySession.dateNumber.text = session.creationDate.getDayNumber() + rowHistorySession.dateDay.text = date.getShortDayName() + rowHistorySession.dateNumber.text = date.getDayNumber() // Title / Game type diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 286f075c..7eaa63c9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -9,7 +9,7 @@ Variant Line Initial Value - There is less than two values to compare! Please change your habits :) + Can\'t show because there is less than two values to display! From fc8ea470a0d71819a1fb9619ad45ee1e33b90ae8 Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 25 Apr 2019 14:53:07 +0200 Subject: [PATCH 032/197] fix rotation issue --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c5824c37..4fdeb098 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,6 +20,7 @@ From 182c67124b9879d18a8d8d5e6c63df2f5245d4dd Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Thu, 25 Apr 2019 15:35:15 +0200 Subject: [PATCH 033/197] remove any month of year played before the first session when using upToNow --- .../pokeranalytics/android/model/Criteria.kt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt index 9df897ab..eb295d5b 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt @@ -24,6 +24,13 @@ fun List>.upToNow(): List> { val currentYear = calendar.get(Calendar.YEAR) val currentMonth = calendar.get(Calendar.MONTH) + val realm = Realm.getDefaultInstance() + val firstSession = realm.where().sort("year", Sort.ASCENDING).findFirst() + realm.close() + + val firstYear = firstSession?.year ?: currentYear + val firstMonth = firstSession?.month ?: currentMonth + val toRemove = this.filter { list -> list.any { it is QueryCondition.AnyYear && it.listOfValues.first() == currentYear } }.filter { list -> @@ -32,6 +39,14 @@ fun List>.upToNow(): List> { } } + val toRemoveBefore = this.filter { list -> + list.any { it is QueryCondition.AnyYear && it.listOfValues.first() == firstYear } + }.filter { list -> + list.any { + it is QueryCondition.AnyMonthOfYear && it.listOfValues.first() < firstMonth + } + } + return this.filter{ list -> var keep = true toRemove.forEach { @@ -39,6 +54,13 @@ fun List>.upToNow(): List> { keep = false } } + firstSession?.let { + toRemoveBefore.forEach { + if (list.containsAll(it)) { + keep = false + } + } + } keep } } From 441b5584026ee772be6e9e80a35c593e9c7993d8 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Thu, 25 Apr 2019 15:48:40 +0200 Subject: [PATCH 034/197] add in patcher the blind string formatting --- .../pokeranalytics/android/model/migrations/Patcher.kt | 8 +++++++- .../net/pokeranalytics/android/model/realm/Session.kt | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt index 498cf6d2..82378a42 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt @@ -1,6 +1,9 @@ package net.pokeranalytics.android.model.migrations import io.realm.Realm +import net.pokeranalytics.android.model.filter.QueryCondition +import net.pokeranalytics.android.model.realm.Filter +import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.SessionSet class Patcher { @@ -11,12 +14,15 @@ class Patcher { val realm = Realm.getDefaultInstance() val sets = realm.where(SessionSet::class.java).findAll() + val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.IsCash)) realm.executeTransaction { sets.forEach { it.computeStats() } - + sessions.forEach { + it.formatBlinds() + } } realm.close() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 839ab4e5..985c9128 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -525,7 +525,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat return blinds ?: NULL_TEXT } - private fun formatBlinds() { + fun formatBlinds() { blinds = null if (cgBigBlind == null) return cgBigBlind?.let { bb -> From cb419988ef0bdecc3756532c54b89fcbd1d0463b Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Thu, 25 Apr 2019 18:39:32 +0200 Subject: [PATCH 035/197] add a new predicates variable to a criteria add the AllMonthsUpToNow --- .../android/model/CriteriaTest.kt | 27 ++++------- .../pokeranalytics/android/model/Criteria.kt | 45 +++++++++++++++++-- .../android/model/filter/QueryCondition.kt | 12 ++++- 3 files changed, 60 insertions(+), 24 deletions(-) diff --git a/app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt index f2a1621b..c0040e5c 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt @@ -23,10 +23,10 @@ class CriteriaTest : BaseFilterInstrumentedUnitTest() { val cal = Calendar.getInstance() cal.time = Date() val s1 = Session.testInstance(100.0, false, cal.time) + val firstValue = cal.get(Calendar.YEAR) cal.add(Calendar.YEAR, 1) Session.testInstance(100.0, true, cal.time) cal.add(Calendar.YEAR, -11) - val firstValue = cal.get(Calendar.YEAR) Session.testInstance(100.0, true, cal.time) cal.add(Calendar.YEAR, 7) Session.testInstance(100.0, true, cal.time) @@ -35,23 +35,23 @@ class CriteriaTest : BaseFilterInstrumentedUnitTest() { cal.add(Calendar.YEAR, 10) Session.testInstance(100.0, true, cal.time) - val lastValue = firstValue + 10 + val lastValue = firstValue + 5 realm.commitTransaction() val years = Criteria.Years.queryConditions as List println("years = ${years.map { it.getDisplayName() }}") - assertEquals(11, years.size) - assertEquals(firstValue, years.first().listOfValues.first()) + assertEquals(16, years.size) + assertEquals(firstValue-10, years.first().listOfValues.first()) assertEquals(lastValue, years.last().listOfValues.first()) } @Test fun combined() { - val critierias = listOf(Criteria.MonthsOfYear, Criteria.DaysOfWeek) - val combined = critierias.combined() + val criterias = listOf(Criteria.MonthsOfYear, Criteria.DaysOfWeek) + val combined = criterias.combined() combined.forEach { it.forEach {qc-> println(qc.getDisplayName()) @@ -82,23 +82,12 @@ class CriteriaTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val critierias = listOf(Criteria.Years, Criteria.MonthsOfYear) - val combined = critierias.combined() - combined.forEach { + val allMonths = Criteria.AllMonthsUpToNow.predicates + allMonths.forEach { it.forEach {qc-> println("<<<<< ${qc.getDisplayName()}") } } - - println("<<<<< reduced") - - val reduced= critierias.combined().upToNow() - reduced.forEach { - it.forEach {qc-> - println("<<<<< ${qc.getDisplayName()}") - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt index eb295d5b..24071bfb 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt @@ -148,11 +148,50 @@ sealed class Criteria { object BankrollTypes: SimpleCriteria(listOf(QueryCondition.IsLive, QueryCondition.IsOnline)) object DayPeriods: SimpleCriteria(listOf(QueryCondition.IsWeekDay, QueryCondition.IsWeekEnd)) object Years: ListCriteria() + object AllMonthsUpToNow: ListCriteria() object Blinds: ListCriteria() object TournamentFees: ListCriteria() object Cash: SimpleCriteria(listOf(QueryCondition.IsCash)) object Tournament: SimpleCriteria(listOf(QueryCondition.IsTournament)) + val predicates: List> + get() { + return when (this) { + is AllMonthsUpToNow -> { + val realm = Realm.getDefaultInstance() + val firstSession= realm.where().sort("startDate", Sort.ASCENDING).findFirst() + val lastSession = realm.where().sort("startDate", Sort.DESCENDING).findFirst() + realm.close() + + val years: ArrayList> = arrayListOf() + + val firstYear = firstSession?.year ?: return years + val firstMonth = firstSession.month ?: return years + val lastYear = lastSession?.year ?: return years + val lastMonth = lastSession.month ?: return years + + for (year in firstYear..lastYear) { + val currentYear = QueryCondition.AnyYear(year) + for (month in 0..11) { + + if (year == firstYear && month < firstMonth) { + continue + } + if (year == lastYear && month > lastMonth) { + continue + } + + val currentMonth = QueryCondition.AnyMonthOfYear(month) + val currentList = listOf(currentYear, currentMonth) + years.add(currentList) + } + } + years + } + else -> listOf(listOf()) + } + } + val queryConditions: List get() { return when (this) { @@ -168,10 +207,10 @@ sealed class Criteria { is TournamentFees -> comparison() is Years -> { val years = arrayListOf() - val calendar = Calendar.getInstance() - calendar.time = Date() - val yearNow = calendar.get(Calendar.YEAR) val realm = Realm.getDefaultInstance() + val lastSession = realm.where().sort("startDate", Sort.DESCENDING).findFirst() + val yearNow = lastSession?.year ?: return years + realm.where().sort("year", Sort.ASCENDING).findFirst()?.year?.let { for (index in 0..(yearNow - it)) { years.add(QueryCondition.AnyYear().apply { diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt index 0f44e1ae..de7cb184 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt @@ -346,16 +346,24 @@ sealed class QueryCondition : FilterElementRow { } } - class AnyMonthOfYear: ListOfInt() { + class AnyMonthOfYear(): ListOfInt() { override fun labelForValue(value: Int): String { return DateFormatSymbols.getInstance(Locale.getDefault()).months[value] } + + constructor(month:Int) : this() { + listOfValues = arrayListOf(month) + } } - class AnyYear: ListOfInt() { + class AnyYear(): ListOfInt() { override fun labelForValue(value: Int): String { return "$value" } + + constructor(year:Int) : this() { + listOfValues = arrayListOf(year) + } } object IsWeekDay: QueryCondition() From c42b8c3454b137c22bb231e707371be1c65240f2 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 26 Apr 2019 10:58:54 +0200 Subject: [PATCH 036/197] Fixes with criteria / aggregation --- .../android/calculus/Calculator.kt | 38 ++++++++++++++++--- .../pokeranalytics/android/calculus/Report.kt | 18 +++++++-- .../pokeranalytics/android/calculus/Stat.kt | 14 +++++-- .../pokeranalytics/android/model/Criteria.kt | 19 +++++++++- .../android/ui/fragment/ReportsFragment.kt | 2 +- .../ui/fragment/StatisticDetailsFragment.kt | 3 +- .../ui/view/rowrepresentable/ReportRow.kt | 6 +-- 7 files changed, 81 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt index 5f679258..5778cea9 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt @@ -10,7 +10,6 @@ import net.pokeranalytics.android.model.filter.filter import net.pokeranalytics.android.model.filter.name import net.pokeranalytics.android.model.realm.ComputableResult import net.pokeranalytics.android.model.realm.SessionSet -import net.pokeranalytics.android.model.upToNow import net.pokeranalytics.android.util.extensions.startOfDay import timber.log.Timber import java.util.* @@ -121,22 +120,51 @@ class Calculator { return when (aggregationType) { AggregationType.SESSION, AggregationType.DURATION -> this.computeGroups(realm, listOf(group), options) AggregationType.MONTH, AggregationType.YEAR -> { - val criteria: List = aggregationType.criterias - this.computeStatsWithComparators(realm, criteria, group.conditions, options) + val queryLists = aggregationType.queryLists + this.computeStatsWithComparators(realm, queryLists, group.conditions, options) } } } + + fun computeStatsWithCriterias( + realm: Realm, + criterias: List, + conditions: List = listOf(), + options: Options = Options() + ): Report { + + val computableGroups: MutableList = mutableListOf() + + criterias.combined().forEach { comparatorConditions -> + + val allConditions = mutableListOf() + allConditions.addAll(conditions) + allConditions.addAll(comparatorConditions) + + val group = ComputableGroup(allConditions.name(), allConditions) + computableGroups.add(group) + + } + + if (computableGroups.size == 0) { + val group = ComputableGroup(conditions.name(), conditions) + computableGroups.add(group) + } + + return this.computeGroups(realm, computableGroups, options) + } + fun computeStatsWithComparators( realm: Realm, - criteria: List = listOf(), + compConditions: List> = listOf(), conditions: List = listOf(), options: Options = Options() ): Report { val computableGroups: MutableList = mutableListOf() - criteria.combined().upToNow().forEach { comparatorConditions -> + compConditions.forEach { comparatorConditions -> val allConditions = mutableListOf() allConditions.addAll(conditions) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt index 01c5f336..0ad7a291 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt @@ -48,7 +48,9 @@ class Report(var options: Calculator.Options) { statToUse?.let { this._results.forEachIndexed { index, results -> - results.computedStat(it)?.progressValue?.let { progressValue -> + val stat = results.computedStat(it) + val progressValue = stat?.progressValue + progressValue?.let { progressValue -> entries.add(Entry(index.toFloat(), progressValue.toFloat(), results)) } } @@ -243,14 +245,15 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu if (this.shouldManageMultiGroupProgressValues) { - this.group.comparedComputedResults?.let { previousResult -> + fun computeProgressValues(computedResults: ComputedResults) { + this.allStats().forEach { computedStat -> val stat = computedStat.stat - previousResult.computedStat(stat)?.let { previousComputedStat -> + computedResults.computedStat(stat)?.let { previousComputedStat -> when (stat) { Stat.NET_RESULT, Stat.HOURLY_DURATION, Stat.BB_NET_RESULT, Stat.BB_SESSION_COUNT, Stat.WINNING_SESSION_COUNT, Stat.TOTAL_BUYIN, Stat.HANDS_PLAYED, Stat.NUMBER_OF_GAMES, Stat.NUMBER_OF_SETS -> { - val previousValue = previousComputedStat.progressValue ?: previousComputedStat.value + val previousValue = previousComputedStat.progressValue ?: 0.0 computedStat.progressValue = previousValue + computedStat.value } else -> {} @@ -259,6 +262,13 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu computedStat.progressValue = computedStat.value } } + + } + + this.group.comparedComputedResults?.let { previousResult -> + computeProgressValues(previousResult) + } ?: run { + computeProgressValues(this) } val netResult = this.computedStat(Stat.NET_RESULT)?.progressValue diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt index 491aa7d7..966b4abe 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt @@ -4,6 +4,7 @@ import android.content.Context import net.pokeranalytics.android.R import net.pokeranalytics.android.exceptions.FormattingException import net.pokeranalytics.android.model.Criteria +import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.interfaces.Timed import net.pokeranalytics.android.ui.graph.AxisFormatting import net.pokeranalytics.android.ui.view.RowRepresentable @@ -47,11 +48,18 @@ enum class AggregationType { } } - val criterias: List + val queryLists: List> get() { return when (this) { - MONTH -> listOf(Criteria.Years, Criteria.MonthsOfYear) - YEAR -> listOf(Criteria.Years) + MONTH -> Criteria.AllMonthsUpToNow.predicates + YEAR -> { + val conditions = Criteria.Years.queryConditions + val list = mutableListOf>() + conditions.forEach { + list.add(listOf(it)) + } + return list + } else -> listOf() } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt index 24071bfb..98b395e0 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt @@ -4,6 +4,16 @@ import io.realm.Realm import io.realm.Sort import io.realm.kotlin.where import net.pokeranalytics.android.exceptions.PokerAnalyticsException +import net.pokeranalytics.android.model.Criteria.Bankrolls.comparison +import net.pokeranalytics.android.model.Criteria.Blinds.comparison +import net.pokeranalytics.android.model.Criteria.Games.comparison +import net.pokeranalytics.android.model.Criteria.Limits.comparison +import net.pokeranalytics.android.model.Criteria.Locations.comparison +import net.pokeranalytics.android.model.Criteria.TableSizes.comparison +import net.pokeranalytics.android.model.Criteria.TournamentFeatures.comparison +import net.pokeranalytics.android.model.Criteria.TournamentFees.comparison +import net.pokeranalytics.android.model.Criteria.TournamentNames.comparison +import net.pokeranalytics.android.model.Criteria.TournamentTypes.comparison import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.realm.* @@ -188,7 +198,14 @@ sealed class Criteria { } years } - else -> listOf(listOf()) + else -> { + val conditions = this.queryConditions + val list = mutableListOf>() + conditions.forEach { + list.add(listOf(it)) + } + return list + } } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt index 488c76ec..1342f2f1 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt @@ -122,7 +122,7 @@ class ReportsFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSour val requiredStats: List = listOf(Stat.NET_RESULT) val options = Calculator.Options(evolutionValues = Calculator.Options.EvolutionValues.STANDARD, stats = requiredStats) - val report = Calculator.computeStatsWithComparators(realm, criteria = criteria, options = options) + val report = Calculator.computeStatsWithCriterias(realm, criterias = criteria, options = options) Timber.d("launchComputation: ${System.currentTimeMillis() - startDate.time}ms") diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt index d580caa2..f5933611 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt @@ -17,7 +17,6 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.* -import net.pokeranalytics.android.model.combined import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.extensions.ChipGroupExtension import net.pokeranalytics.android.ui.extensions.hideWithAnimation @@ -127,7 +126,7 @@ class StatisticDetailsFragment : PokerAnalyticsFragment() { when (aggregationType) { AggregationType.MONTH, AggregationType.YEAR -> { - val queryConditions = aggregationType.criterias.combined() + val queryConditions = aggregationType.queryLists if (queryConditions.size < 2) { Toast.makeText(context, R.string.less_then_2_values_for_display, Toast.LENGTH_LONG).show() return diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/ReportRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/ReportRow.kt index 0d10b538..defbd5ae 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/ReportRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/ReportRow.kt @@ -14,7 +14,7 @@ enum class ReportRow : RowRepresentable { DAY_OF_WEEKS, GENERAL, LOCATIONS, - NUMBER_OF_TABLES, +// NUMBER_OF_TABLES, TOURNAMENT_TYPES, GAME; @@ -39,7 +39,7 @@ enum class ReportRow : RowRepresentable { DAY_OF_WEEKS -> R.string.day_of_the_week GENERAL -> R.string.general LOCATIONS -> R.string.locations - NUMBER_OF_TABLES -> R.string.number_of_tables +// NUMBER_OF_TABLES -> R.string.number_of_tables TOURNAMENT_TYPES -> R.string.tournament_type_complete GAME -> R.string.game } @@ -55,7 +55,7 @@ enum class ReportRow : RowRepresentable { DAY_OF_WEEKS -> listOf(Criteria.DaysOfWeek) GENERAL -> listOf(Criteria.SessionTypes, Criteria.BankrollTypes) LOCATIONS -> listOf(Criteria.Locations) - NUMBER_OF_TABLES -> listOf() //TODO +// NUMBER_OF_TABLES -> listOf() //TODO TOURNAMENT_TYPES -> listOf(Criteria.TournamentTypes) GAME -> listOf(Criteria.Games) } From 96925f525f7f5f96af6bb6375ab38feddf4e02ee Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 26 Apr 2019 11:06:51 +0200 Subject: [PATCH 037/197] cleanup --- .../net/pokeranalytics/android/calculus/Report.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt index 0ad7a291..4f5cb92e 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt @@ -48,9 +48,7 @@ class Report(var options: Calculator.Options) { statToUse?.let { this._results.forEachIndexed { index, results -> - val stat = results.computedStat(it) - val progressValue = stat?.progressValue - progressValue?.let { progressValue -> + results.computedStat(it)?.progressValue?.let { progressValue -> entries.add(Entry(index.toFloat(), progressValue.toFloat(), results)) } } @@ -73,7 +71,7 @@ class Report(var options: Calculator.Options) { } } - val label = statToUse?.name ?: "" + val label = statToUse?.name ?: "" return DataSetFactory.barDataSetInstance(entries, label, context) } @@ -180,7 +178,8 @@ class ComputableGroup(name: String = "", conditions: List = list } -class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValues: Boolean = false) : GraphUnderlyingEntry { +class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValues: Boolean = false) : + GraphUnderlyingEntry { /** * The session group used to computed the stats @@ -256,7 +255,8 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu val previousValue = previousComputedStat.progressValue ?: 0.0 computedStat.progressValue = previousValue + computedStat.value } - else -> {} + else -> { + } } } ?: run { computedStat.progressValue = computedStat.value @@ -328,7 +328,8 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu computedStat.progressValue = Stat.returnOnInvestment(netResult, totalBuyin) } } - else -> {} + else -> { + } } } From 5e32a8938cf591a4b840f58d6e87122859973765 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 26 Apr 2019 11:44:48 +0200 Subject: [PATCH 038/197] Fixing crash --- .../android/ui/fragment/TableReportFragment.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/TableReportFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/TableReportFragment.kt index 07cdc63c..71a1243b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/TableReportFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/TableReportFragment.kt @@ -4,12 +4,14 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.recyclerview.widget.LinearLayoutManager import io.realm.Realm import kotlinx.android.synthetic.main.fragment_stats.* import kotlinx.coroutines.* import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.* +import net.pokeranalytics.android.model.realm.ComputableResult import net.pokeranalytics.android.ui.activity.StatisticDetailsActivity import net.pokeranalytics.android.ui.adapter.DisplayDescriptor import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter @@ -148,6 +150,12 @@ open class TableReportFragment : SessionObserverFragment(), StaticRowRepresentab override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { + val cr = getRealm().where(ComputableResult::class.java).findAll() + if (cr.size < 2) { + Toast.makeText(context, R.string.less_then_2_values_for_display, Toast.LENGTH_LONG).show() + return + } + if (row is StatRow && row.stat.hasEvolutionGraph) { // queryWith groups From feb62b78d6e8546c07073a3eb42c49d7e0be36cb Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 26 Apr 2019 17:41:22 +0200 Subject: [PATCH 039/197] Refactoring of List into Query, minus sorting --- app/build.gradle | 2 +- .../android/PokerAnalyticsApplication.kt | 4 +- .../android/calculus/Calculator.kt | 55 ++---- .../pokeranalytics/android/calculus/Report.kt | 25 ++- .../pokeranalytics/android/calculus/Stat.kt | 14 +- .../calculus/bankroll/BankrollCalculator.kt | 10 +- .../calculus/bankroll/BankrollReport.kt | 15 +- .../pokeranalytics/android/model/Criteria.kt | 187 ++++++++---------- .../android/model/filter/Filterable.kt | 10 +- .../android/model/filter/Query.kt | 63 ++++++ .../android/model/filter/QueryCondition.kt | 18 +- .../android/model/migrations/Patcher.kt | 3 +- .../android/model/realm/Filter.kt | 5 +- .../ui/fragment/CalendarDetailsFragment.kt | 33 ++-- .../android/ui/fragment/CalendarFragment.kt | 21 +- .../ui/fragment/StatisticDetailsFragment.kt | 4 +- .../android/ui/fragment/StatisticsFragment.kt | 8 +- .../view/rowrepresentable/FilterSectionRow.kt | 32 +-- 18 files changed, 257 insertions(+), 252 deletions(-) create mode 100644 app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt diff --git a/app/build.gradle b/app/build.gradle index fa061394..758e8fb3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 18 + versionCode 19 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index a16c0963..26ddf597 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -52,7 +52,7 @@ class PokerAnalyticsApplication : Application() { if (BuildConfig.DEBUG) { Timber.d("UserPreferences.defaultCurrency: ${UserDefaults.currency.symbol}") -// this.createFakeSessions() + this.createFakeSessions() } Patcher.patchBreaks() @@ -69,7 +69,7 @@ class PokerAnalyticsApplication : Application() { if (sessionsCount < 1) { GlobalScope.launch { - FakeDataManager.createFakeSessions(2000) + FakeDataManager.createFakeSessions(200) } } diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt index 5778cea9..1bd946d7 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt @@ -5,9 +5,9 @@ import net.pokeranalytics.android.calculus.Stat.* import net.pokeranalytics.android.model.Criteria import net.pokeranalytics.android.model.combined import net.pokeranalytics.android.model.extensions.hourlyDuration +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.filter.filter -import net.pokeranalytics.android.model.filter.name import net.pokeranalytics.android.model.realm.ComputableResult import net.pokeranalytics.android.model.realm.SessionSet import net.pokeranalytics.android.util.extensions.startOfDay @@ -120,8 +120,7 @@ class Calculator { return when (aggregationType) { AggregationType.SESSION, AggregationType.DURATION -> this.computeGroups(realm, listOf(group), options) AggregationType.MONTH, AggregationType.YEAR -> { - val queryLists = aggregationType.queryLists - this.computeStatsWithComparators(realm, queryLists, group.conditions, options) + this.computeStatsWithCriterias(realm, aggregationType.criterias, group.query, options) } } } @@ -129,54 +128,24 @@ class Calculator { fun computeStatsWithCriterias( realm: Realm, - criterias: List, - conditions: List = listOf(), + criterias: List = listOf(), + query: Query = Query(), options: Options = Options() ): Report { val computableGroups: MutableList = mutableListOf() - criterias.combined().forEach { comparatorConditions -> + criterias.combined().forEach { comparatorQuery -> - val allConditions = mutableListOf() - allConditions.addAll(conditions) - allConditions.addAll(comparatorConditions) + comparatorQuery.merge(query) - val group = ComputableGroup(allConditions.name(), allConditions) + val group = ComputableGroup(comparatorQuery) computableGroups.add(group) } if (computableGroups.size == 0) { - val group = ComputableGroup(conditions.name(), conditions) - computableGroups.add(group) - } - - return this.computeGroups(realm, computableGroups, options) - } - - fun computeStatsWithComparators( - realm: Realm, - compConditions: List> = listOf(), - conditions: List = listOf(), - options: Options = Options() - ): Report { - - val computableGroups: MutableList = mutableListOf() - - compConditions.forEach { comparatorConditions -> - - val allConditions = mutableListOf() - allConditions.addAll(conditions) - allConditions.addAll(comparatorConditions) - - val group = ComputableGroup(allConditions.name(), allConditions) - computableGroups.add(group) - - } - - if (computableGroups.size == 0) { - val group = ComputableGroup(conditions.name(), conditions) + val group = ComputableGroup(query) computableGroups.add(group) } @@ -401,7 +370,7 @@ class Calculator { sessionSets.forEach { sessionSet -> tIndex++ - val setStats = SSStats(sessionSet, computableGroup.conditions) + val setStats = SSStats(sessionSet, computableGroup.query) tRatedNetSum += setStats.ratedNet tBBSum += setStats.bbSum @@ -527,7 +496,7 @@ class Calculator { if (gHourlyDuration != null) { var hourlyStdSum = 0.0 sessionSets.forEach { set -> - val ssStats = SSStats(set, computableGroup.conditions) + val ssStats = SSStats(set, computableGroup.query) val sHourlyRate = ssStats.hourlyRate hourlyStdSum += Math.pow(sHourlyRate - hourlyRate, 2.0) } @@ -545,7 +514,7 @@ class Calculator { } -class SSStats(sessionSet: SessionSet, conditions: List) { // Session Set Stats +class SSStats(sessionSet: SessionSet, query: Query) { // Session Set Stats var hourlyDuration: Double = 0.0 var estimatedHands: Double = 0.0 @@ -563,7 +532,7 @@ class SSStats(sessionSet: SessionSet, conditions: List) { // Ses this.initStatsWithSet(sessionSet) } else { // dynamically filter and compute subset val setSessions = sessionSet.sessions!! - val filteredSessions = setSessions.filter(conditions) + val filteredSessions = setSessions.filter(query) if (setSessions.size == filteredSessions.size) { this.initStatsWithSet(sessionSet) } else { diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt index 4f5cb92e..d3ce7f52 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt @@ -5,6 +5,7 @@ import com.github.mikephil.charting.data.* import io.realm.Realm import io.realm.RealmResults import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.interfaces.Timed import net.pokeranalytics.android.model.realm.ComputableResult @@ -94,17 +95,29 @@ class Report(var options: Calculator.Options) { /** * A sessionGroup of computable items identified by a name */ -class ComputableGroup(name: String = "", conditions: List = listOf(), stats: List? = null) { +class ComputableGroup(query: Query, stats: List? = null) { + +// constructor(query: Query, stats: List? = null) : this(query.name, query.conditions) +// +// private constructor(name: String = "", conditions: List = listOf(), stats: List? = null) + + var query: Query = query /** * The display name of the group */ - var name: String = name + var name: String = "" + get() { + return this.query.name + } /** - * A list of conditions to get + * A list of _conditions to get */ - var conditions: List = conditions + var conditions: List = listOf() + get() { + return this.query.conditions + } /** * The list of endedSessions to compute @@ -124,7 +137,7 @@ class ComputableGroup(name: String = "", conditions: List = list } val sortedField = if (sorted) "session.startDate" else null - val computables = Filter.queryOn(realm, this.conditions, sortedField) + val computables = Filter.queryOn(realm, this.query, sortedField) this._computables = computables return computables } @@ -146,7 +159,7 @@ class ComputableGroup(name: String = "", conditions: List = list } val sortedField = if (sorted) SessionSet.Field.START_DATE.identifier else null - val sets = Filter.queryOn(realm, this.conditions, sortedField) + val sets = Filter.queryOn(realm, this.query, sortedField) this._sessionSets = sets return sets } diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt index 966b4abe..2d204891 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt @@ -4,7 +4,6 @@ import android.content.Context import net.pokeranalytics.android.R import net.pokeranalytics.android.exceptions.FormattingException import net.pokeranalytics.android.model.Criteria -import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.interfaces.Timed import net.pokeranalytics.android.ui.graph.AxisFormatting import net.pokeranalytics.android.ui.view.RowRepresentable @@ -48,18 +47,11 @@ enum class AggregationType { } } - val queryLists: List> + val criterias: List get() { return when (this) { - MONTH -> Criteria.AllMonthsUpToNow.predicates - YEAR -> { - val conditions = Criteria.Years.queryConditions - val list = mutableListOf>() - conditions.forEach { - list.add(listOf(it)) - } - return list - } + MONTH -> listOf(Criteria.AllMonthsUpToNow) + YEAR -> listOf(Criteria.Years) else -> listOf() } } diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt index e56689c2..2563b660 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt @@ -32,21 +32,21 @@ class BankrollCalculator { report.transactionsNet = transactionNet report.initial = initialValue - val queryConditions = setup.queryConditions - val transactions = Filter.queryOn(realm, queryConditions) + val query = setup.query + val transactions = Filter.queryOn(realm, query) report.addDatedItems(transactions) transactions.forEach { report.addTransaction(it) } - val sessions = Filter.queryOn(realm, queryConditions) + val sessions = Filter.queryOn(realm, query) report.addDatedItems(sessions) if (setup.virtualBankroll) { val options = Calculator.Options(stats = listOf(Stat.NET_RESULT, Stat.HOURLY_RATE, Stat.STANDARD_DEVIATION_HOURLY)) - val group = ComputableGroup(conditions = queryConditions) + val group = ComputableGroup(query) val result = Calculator.compute(realm, group, options) result.computedStat(Stat.NET_RESULT)?.let { report.netResult = it.value @@ -55,7 +55,7 @@ class BankrollCalculator { } else { - val results = Filter.queryOn(realm, queryConditions) + val results = Filter.queryOn(realm, query) report.netResult = results.sum("net").toDouble() } diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt index 53d8ff4e..313979f5 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt @@ -3,6 +3,7 @@ package net.pokeranalytics.android.calculus.bankroll import android.content.Context import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.data.LineDataSet +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.interfaces.DatedValue import net.pokeranalytics.android.model.realm.Bankroll @@ -153,25 +154,25 @@ class BankrollReportSetup(val bankroll: Bankroll? = null, val from: Date? = null return this.bankroll == null } - val queryConditions: List + val query: Query get() { - val conditions = mutableListOf() + val query = Query() + this.bankroll?.let { val bankrollCondition = QueryCondition.AnyBankroll(bankroll) - conditions.add(bankrollCondition) + query.add(bankrollCondition) } this.from?.let { val fromCondition = QueryCondition.StartedFromDate() fromCondition.singleValue = it - conditions.add(fromCondition) + query.add(fromCondition) } this.to?.let { val toCondition = QueryCondition.StartedToDate() toCondition.singleValue = it - conditions.add(toCondition) + query.add(toCondition) } - - return conditions + return query } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt index 98b395e0..8dfbcec0 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt @@ -14,118 +14,92 @@ import net.pokeranalytics.android.model.Criteria.TournamentFeatures.comparison import net.pokeranalytics.android.model.Criteria.TournamentFees.comparison import net.pokeranalytics.android.model.Criteria.TournamentNames.comparison import net.pokeranalytics.android.model.Criteria.TournamentTypes.comparison +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.realm.* -import java.util.* -import kotlin.collections.ArrayList -fun List.combined(): List> { - val comparatorList = ArrayList>() - this.forEach { - comparatorList.add(it.queryConditions) +fun List.combined(): List { + val comparatorList = ArrayList>() + this.forEach { criteria -> + comparatorList.add(criteria.queries) } return getCombinations(comparatorList) } -fun List>.upToNow(): List> { - val calendar = Calendar.getInstance() - calendar.time = Date() - val currentYear = calendar.get(Calendar.YEAR) - val currentMonth = calendar.get(Calendar.MONTH) +fun getCombinations(queries: List>): List { - val realm = Realm.getDefaultInstance() - val firstSession = realm.where().sort("year", Sort.ASCENDING).findFirst() - realm.close() + if (queries.size == 0) { return listOf() } - val firstYear = firstSession?.year ?: currentYear - val firstMonth = firstSession?.month ?: currentMonth + val mutableQueries = queries.toMutableList() + var combinations = mutableQueries.removeAt(0) - val toRemove = this.filter { list -> - list.any { it is QueryCondition.AnyYear && it.listOfValues.first() == currentYear } - }.filter { list -> - list.any { - it is QueryCondition.AnyMonthOfYear && it.listOfValues.first() > currentMonth - } - } - - val toRemoveBefore = this.filter { list -> - list.any { it is QueryCondition.AnyYear && it.listOfValues.first() == firstYear } - }.filter { list -> - list.any { - it is QueryCondition.AnyMonthOfYear && it.listOfValues.first() < firstMonth - } - } + for (queryList in mutableQueries) { - return this.filter{ list -> - var keep = true - toRemove.forEach { - if (list.containsAll(it)) { - keep = false - } - } - firstSession?.let { - toRemoveBefore.forEach { - if (list.containsAll(it)) { - keep = false - } - } - } - keep - } -} - -fun getCombinations(lists: List>): List> { - var combinations: LinkedHashSet> = LinkedHashSet() - var newCombinations: LinkedHashSet> - - var index = 0 - - // extract each of the integers in the first list - // and add each to ints as a new list - if (lists.isNotEmpty()) { - for (i in lists[0]) { - val newList = ArrayList() - newList.add(i) - combinations.add(newList) - } - index++ - } - while (index < lists.size) { - val nextList = lists[index] - newCombinations = LinkedHashSet() - for (first in combinations) { - for (second in nextList) { - val newList = ArrayList() - newList.addAll(first) - newList.add(second) - newCombinations.add(newList) + val newCombinations = mutableListOf() + combinations.forEach { combinedQuery -> + queryList.forEach { queryToAdd -> + val nq = Query().merge(combinedQuery).merge(queryToAdd) + newCombinations.add(nq) } } combinations = newCombinations - - index++ } - return combinations.toList() + return combinations } +//fun getCombinations(lists: List): List { +// var combinations: LinkedHashSet = LinkedHashSet() +// var newCombinations: LinkedHashSet +// +// var index = 0 +// +// // extract each of the integers in the first list +// // and add each to ints as a new list +// if (lists.isNotEmpty()) { +// for (i in lists[0]) { +// val newList = ArrayList() +// newList.add(i) +// combinations.add(newList) +// } +// index++ +// } +// while (index < lists.size) { +// val nextList = lists[index] +// newCombinations = LinkedHashSet() +// for (first in combinations) { +// for (second in nextList) { +// val newList = ArrayList() +// newList.addAll(first) +// newList.add(second) +// newCombinations.add(newList) +// } +// } +// combinations = newCombinations +// +// index++ +// } +// +// return combinations.toList() +//} + sealed class Criteria { abstract class RealmCriteria : Criteria() { - inline fun comparison(): List { + inline fun comparison(): List { return compare, T>() - .sorted() +// .sorted() } } abstract class SimpleCriteria(private val conditions:List): Criteria() { - fun comparison(): List { - return conditions + fun comparison(): List { + return conditions.map { Query(it) } } } abstract class ListCriteria : Criteria() { - inline fun , reified S:Comparable> comparison(): List { + inline fun , reified S : Comparable> comparison(): List { QueryCondition.distinct()?.let { val values = it.mapNotNull { session -> when (this) { @@ -137,9 +111,9 @@ sealed class Criteria { else -> null } }.distinct() - return compareList(values = values).sorted() + return compareList(values = values)//.sorted() } - return listOf() + return listOf() } } @@ -164,7 +138,7 @@ sealed class Criteria { object Cash: SimpleCriteria(listOf(QueryCondition.IsCash)) object Tournament: SimpleCriteria(listOf(QueryCondition.IsTournament)) - val predicates: List> + val queries: List get() { return when (this) { is AllMonthsUpToNow -> { @@ -173,7 +147,7 @@ sealed class Criteria { val lastSession = realm.where().sort("startDate", Sort.DESCENDING).findFirst() realm.close() - val years: ArrayList> = arrayListOf() + val years: ArrayList = arrayListOf() val firstYear = firstSession?.year ?: return years val firstMonth = firstSession.month ?: return years @@ -192,24 +166,19 @@ sealed class Criteria { } val currentMonth = QueryCondition.AnyMonthOfYear(month) - val currentList = listOf(currentYear, currentMonth) - years.add(currentList) + val query = Query(currentYear, currentMonth) + years.add(query) } } years } else -> { - val conditions = this.queryConditions - val list = mutableListOf>() - conditions.forEach { - list.add(listOf(it)) - } - return list + return this.queryConditions } } } - val queryConditions: List + val queryConditions: List get() { return when (this) { is Bankrolls -> comparison() @@ -223,20 +192,21 @@ sealed class Criteria { is TableSizes -> comparison() is TournamentFees -> comparison() is Years -> { - val years = arrayListOf() + val years = arrayListOf() val realm = Realm.getDefaultInstance() val lastSession = realm.where().sort("startDate", Sort.DESCENDING).findFirst() val yearNow = lastSession?.year ?: return years realm.where().sort("year", Sort.ASCENDING).findFirst()?.year?.let { for (index in 0..(yearNow - it)) { - years.add(QueryCondition.AnyYear().apply { + val yearCondition = QueryCondition.AnyYear().apply { listOfValues = arrayListOf(yearNow - index) - }) + } + years.add(Query(yearCondition)) } } realm.close() - years.sorted() + years//.sorted() } is Blinds -> comparison() else -> throw PokerAnalyticsException.QueryTypeUnhandled @@ -244,24 +214,27 @@ sealed class Criteria { } companion object { - inline fun < reified S : QueryCondition.QueryDataCondition, reified T : NameManageable > compare(): List { - val objects = arrayListOf() + inline fun , reified T : NameManageable> compare(): List { + val objects = mutableListOf() val realm = Realm.getDefaultInstance() realm.where().findAll().forEach { - objects.add((QueryCondition.getInstance() as S).apply { + val condition = (QueryCondition.getInstance() as S).apply { setObject(it) - }) + } + val query = Query(condition) + objects.add(query) } realm.close() return objects } - inline fun < reified S : QueryCondition.ListOfValues, T:Any > compareList(values:List): List { - val objects = arrayListOf() + inline fun < reified S : QueryCondition.ListOfValues, T:Any > compareList(values:List): List { + val objects = mutableListOf() values.forEach { - objects.add((S::class.java.newInstance()).apply { + val condition =(S::class.java.newInstance()).apply { listOfValues = arrayListOf(it) - }) + } + objects.add(Query(condition)) } return objects } diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/Filterable.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/Filterable.kt index 7ace8c8d..eefa27fb 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/Filterable.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/Filterable.kt @@ -3,11 +3,7 @@ package net.pokeranalytics.android.model.filter import io.realm.RealmModel import io.realm.RealmResults import net.pokeranalytics.android.exceptions.PokerAnalyticsException -import net.pokeranalytics.android.model.realm.ComputableResult -import net.pokeranalytics.android.model.realm.Session -import net.pokeranalytics.android.model.realm.SessionSet -import net.pokeranalytics.android.model.realm.Transaction -import net.pokeranalytics.android.model.realm.Result +import net.pokeranalytics.android.model.realm.* /** * We want to be able to store filters in the database: @@ -51,8 +47,8 @@ interface Filterable : RealmModel { } -inline fun RealmResults.filter(conditions: List) : RealmResults { - return conditions.queryWith(this.where()).findAll() +inline fun RealmResults.filter(query: Query) : RealmResults { + return query.queryWith(this.where()).findAll() } class FilterHelper { diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt new file mode 100644 index 00000000..c8298a16 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt @@ -0,0 +1,63 @@ +package net.pokeranalytics.android.model.filter + +import io.realm.RealmQuery + +fun List.mapFirstCondition() : List { + return this.map { it.conditions.first() } +} + +class Query : Comparable { + + override fun compareTo(other: QueryCondition): Int { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + constructor(vararg elements: QueryCondition) { + if (elements.size > 0) { + this.add(elements.asList()) + } + } + + private val _conditions: MutableList = mutableListOf() + val conditions: List + get() { + return this._conditions + } + + fun add(vararg elements: QueryCondition) { + if (elements.size > 0) { + this.add(elements.asList()) + } + } + + fun add(queryCondition: QueryCondition) { + this._conditions.add(queryCondition) + } + + fun remove(queryCondition: QueryCondition) { + this._conditions.remove(queryCondition) + } + + fun add(queryConditions: List) { + this._conditions.addAll(queryConditions) + } + + val name: String + get() { + return this._conditions.joinToString(" : ") { it.getDisplayName() } + } + + inline fun queryWith(query: RealmQuery): RealmQuery { + var realmQuery = query + this.conditions.forEach { + realmQuery = it.queryWith(realmQuery) + } + return realmQuery + } + + fun merge(query: Query) : Query { + this.add(query.conditions) + return this + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt index de7cb184..68b8faed 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt @@ -26,28 +26,13 @@ import java.text.DateFormatSymbols import java.util.* import kotlin.collections.ArrayList -fun List.name() : String { - return this.map { it.getDisplayName() }.joinToString(" : ") -} - -//inline fun List.query(realm: Realm): RealmQuery { -// return this.queryWith(realm.where()) -//} - -inline fun List.queryWith(query: RealmQuery): RealmQuery { - var realmQuery = query - this.forEach { - realmQuery = it.queryWith(realmQuery) - } - return realmQuery -} - /** * Enum describing the way a query should be handled * Some queries requires a value to be checked upon through equals, in, more, less, between */ sealed class QueryCondition : FilterElementRow { + companion object { inline fun < reified T:QueryCondition> more():T { return T::class.java.newInstance().apply { this.operator = Operator.MORE } } inline fun < reified T:QueryCondition> less():T { return T::class.java.newInstance().apply { this.operator = Operator.LESS } } @@ -118,6 +103,7 @@ sealed class QueryCondition : FilterElementRow { open var operator: Operator = Operator.ANY abstract class ListOfValues: QueryCondition(), Comparable> where T:Comparable { + abstract var listOfValues: ArrayList abstract fun labelForValue(value:T): String diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt index 82378a42..03fa29bf 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt @@ -1,6 +1,7 @@ package net.pokeranalytics.android.model.migrations import io.realm.Realm +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.realm.Filter import net.pokeranalytics.android.model.realm.Session @@ -14,7 +15,7 @@ class Patcher { val realm = Realm.getDefaultInstance() val sets = realm.where(SessionSet::class.java).findAll() - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.IsCash)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.IsCash)) realm.executeTransaction { sets.forEach { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt index d9c2c159..e485ca01 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt @@ -4,6 +4,7 @@ import io.realm.* import io.realm.annotations.PrimaryKey import io.realm.kotlin.where import net.pokeranalytics.android.model.filter.Filterable +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow import timber.log.Timber @@ -29,9 +30,9 @@ open class Filter : RealmObject() { return realm.where().equalTo("id", filterId).findFirst() } - inline fun queryOn(realm: Realm, queries: List, sortField: String? = null): RealmResults { + inline fun queryOn(realm: Realm, query: Query, sortField: String? = null): RealmResults { var realmQuery = realm.where() - queries.forEach { + query.conditions.forEach { realmQuery = it.queryWith(realmQuery) } sortField?.let { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarDetailsFragment.kt index e9a272aa..7a7bd784 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarDetailsFragment.kt @@ -18,7 +18,7 @@ import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.ComputedResults import net.pokeranalytics.android.calculus.Stat -import net.pokeranalytics.android.model.Criteria +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.ui.activity.StatisticDetailsActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity @@ -173,22 +173,31 @@ class CalendarDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable val startDate = Date() val realm = Realm.getDefaultInstance() - val conditions = ArrayList().apply { - addAll(computedResults.group.conditions) - // Remove session type conditions - removeAll(Criteria.Cash.queryConditions) - removeAll(Criteria.Tournament.queryConditions) - - when (sessionTypeCondition) { - QueryCondition.IsCash -> addAll(Criteria.Cash.queryConditions) - QueryCondition.IsTournament -> addAll(Criteria.Tournament.queryConditions) - } + val query = Query().merge(computedResults.group.query) + query.remove(QueryCondition.IsCash) + query.remove(QueryCondition.IsTournament) + when (sessionTypeCondition) { + QueryCondition.IsCash -> query.add(QueryCondition.IsCash) + QueryCondition.IsTournament -> query.add(QueryCondition.IsTournament) } +// val conditions = ArrayList().apply { +// addAll(computedResults.group.conditions) +// +// // Remove session type _conditions +// removeAll(Criteria.Cash.queryConditions) +// removeAll(Criteria.Tournament.queryConditions) +// +// when (sessionTypeCondition) { +// QueryCondition.IsCash -> addAll(Criteria.Cash.queryConditions) +// QueryCondition.IsTournament -> addAll(Criteria.Tournament.queryConditions) +// } +// } + val requiredStats: List = listOf(Stat.LOCATIONS_PLAYED, Stat.LONGEST_STREAKS, Stat.DAYS_PLAYED, Stat.STANDARD_DEVIATION_HOURLY) val options = Calculator.Options(evolutionValues = Calculator.Options.EvolutionValues.STANDARD, stats = requiredStats) - val report = Calculator.computeStatsWithComparators(realm, conditions = conditions, options = options) + val report = Calculator.computeStatsWithCriterias(realm, listOf(), query, options) Timber.d("Report take: ${System.currentTimeMillis() - startDate.time}ms") diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarFragment.kt index e5e54964..d04eada1 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarFragment.kt @@ -240,21 +240,20 @@ class CalendarFragment : SessionObserverFragment(), CoroutineScope, StaticRowRep // Compute data per AnyYear and AnyMonthOfYear - println(">>>> ${Criteria.MonthsOfYear.queryConditions.map { it.id }}") +// println(">>>> ${Criteria.MonthsOfYear.queryConditions.map { it.id }}") - val monthConditions = when (sessionTypeCondition) { - QueryCondition.IsCash -> listOf(Criteria.Years, Criteria.MonthsOfYear, Criteria.Cash).combined() - QueryCondition.IsTournament -> listOf(Criteria.Years, Criteria.MonthsOfYear, Criteria.Tournament).combined() + val monthlyQueries = when (sessionTypeCondition) { + QueryCondition.IsCash -> listOf(Criteria.AllMonthsUpToNow, Criteria.Cash).combined() + QueryCondition.IsTournament -> listOf(Criteria.AllMonthsUpToNow, Criteria.Tournament).combined() else -> listOf(Criteria.Years, Criteria.MonthsOfYear).combined() } - monthConditions.forEach { conditions -> - - val report = Calculator.computeStatsWithComparators(realm, conditions = conditions, options = options) + monthlyQueries.forEach { query -> + val report = Calculator.computeStatsWithCriterias(realm, query = query, options = options) report.results.forEach { computedResults -> if (!computedResults.isEmpty) { // Set date data - conditions.forEach { condition -> + query.conditions.forEach { condition -> when (condition) { is QueryCondition.AnyYear -> calendar.set(Calendar.YEAR, condition.listOfValues.first()) is QueryCondition.AnyMonthOfYear -> calendar.set(Calendar.MONTH, condition.listOfValues.first()) @@ -275,12 +274,12 @@ class CalendarFragment : SessionObserverFragment(), CoroutineScope, StaticRowRep else -> listOf(Criteria.Years).combined() } - yearConditions.forEach { conditions -> - val report = Calculator.computeStatsWithComparators(realm, conditions = conditions, options = options) + yearConditions.forEach { query -> + val report = Calculator.computeStatsWithCriterias(realm, query = query, options = options) report.results.forEach { computedResults -> if (!computedResults.isEmpty) { // Set date data - conditions.forEach { condition -> + query.conditions.forEach { condition -> when (condition) { is QueryCondition.AnyYear -> calendar.set(Calendar.YEAR, condition.listOfValues.first()) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt index f5933611..1cf2b32c 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.* +import net.pokeranalytics.android.model.combined import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.extensions.ChipGroupExtension import net.pokeranalytics.android.ui.extensions.hideWithAnimation @@ -126,8 +127,7 @@ class StatisticDetailsFragment : PokerAnalyticsFragment() { when (aggregationType) { AggregationType.MONTH, AggregationType.YEAR -> { - val queryConditions = aggregationType.queryLists - if (queryConditions.size < 2) { + if (aggregationType.criterias.combined().size < 2) { Toast.makeText(context, R.string.less_then_2_values_for_display, Toast.LENGTH_LONG).show() return } 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 336b56fd..b1d7931b 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 @@ -12,6 +12,7 @@ import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.ComputableGroup import net.pokeranalytics.android.calculus.Report import net.pokeranalytics.android.calculus.Stat +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable @@ -120,7 +121,8 @@ class StatisticsFragment : TableReportFragment() { Stat.AVERAGE_HOURLY_DURATION, Stat.HOURLY_DURATION ) - val allSessionGroup = ComputableGroup(stringAll, listOf(), allStats) + val allSessionGroup = ComputableGroup(Query(), allStats) + val cgStats: List = listOf( Stat.NET_RESULT, Stat.HOURLY_RATE, @@ -132,10 +134,10 @@ class StatisticsFragment : TableReportFragment() { Stat.NUMBER_OF_GAMES, Stat.AVERAGE_BUYIN ) - val cgSessionGroup = ComputableGroup(stringCashGame, listOf(QueryCondition.IsCash), cgStats) + val cgSessionGroup = ComputableGroup(Query(QueryCondition.IsCash), cgStats) val tStats: List = listOf(Stat.NET_RESULT, Stat.HOURLY_RATE, Stat.ROI, Stat.WIN_RATIO, Stat.NUMBER_OF_GAMES, Stat.AVERAGE_BUYIN) - val tSessionGroup = ComputableGroup(stringTournament, listOf(QueryCondition.IsTournament), tStats) + val tSessionGroup = ComputableGroup(Query(QueryCondition.IsTournament), tStats) Timber.d(">>>>> Start computations...") diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt index f4bd2859..a68879e5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt @@ -3,7 +3,7 @@ package net.pokeranalytics.android.ui.view.rowrepresentable import net.pokeranalytics.android.R import net.pokeranalytics.android.model.Criteria import net.pokeranalytics.android.model.filter.QueryCondition -import net.pokeranalytics.android.model.filter.QueryCondition.NumberOfTable.* +import net.pokeranalytics.android.model.filter.mapFirstCondition import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType @@ -59,11 +59,11 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable { when (this@FilterSectionRow) { // General - CASH_TOURNAMENT -> Criteria.SessionTypes.queryConditions - LIVE_ONLINE -> Criteria.BankrollTypes.queryConditions - GAME -> Criteria.Games.queryConditions - LIMIT_TYPE -> Criteria.Limits.queryConditions - TABLE_SIZE -> Criteria.TableSizes.queryConditions + CASH_TOURNAMENT -> Criteria.SessionTypes.queryConditions.mapFirstCondition() + LIVE_ONLINE -> Criteria.BankrollTypes.queryConditions.mapFirstCondition() + GAME -> Criteria.Games.queryConditions.mapFirstCondition() + LIMIT_TYPE -> Criteria.Limits.queryConditions.mapFirstCondition() + TABLE_SIZE -> Criteria.TableSizes.queryConditions.mapFirstCondition() // Date DYNAMIC_DATE -> arrayListOf( QueryCondition.IsToday, @@ -76,9 +76,9 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable { FIXED_DATE -> arrayListOf(QueryCondition.StartedFromDate(), QueryCondition.EndedToDate()) DURATION -> arrayListOf(QueryCondition.PastDay()) WEEKDAYS_OR_WEEKEND -> arrayListOf(QueryCondition.IsWeekDay, QueryCondition.IsWeekEnd) - YEAR -> Criteria.Years.queryConditions - DAY_OF_WEEK -> Criteria.DaysOfWeek.queryConditions - MONTH_OF_YEAR -> Criteria.MonthsOfYear.queryConditions + YEAR -> Criteria.Years.queryConditions.mapFirstCondition() + DAY_OF_WEEK -> Criteria.DaysOfWeek.queryConditions.mapFirstCondition() + MONTH_OF_YEAR -> Criteria.MonthsOfYear.queryConditions.mapFirstCondition() // Duration SESSION_DURATION -> QueryCondition.moreOrLess() @@ -88,21 +88,21 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable { SESSIONS -> arrayListOf(QueryCondition.LastGame(), QueryCondition.LastSession()) // Cash - BLIND -> Criteria.Blinds.queryConditions + BLIND -> Criteria.Blinds.queryConditions.mapFirstCondition() // CASH_RE_BUY_COUNT -> QueryCondition.moreOrLess() // Tournament - TOURNAMENT_TYPE -> Criteria.TournamentTypes.queryConditions + TOURNAMENT_TYPE -> Criteria.TournamentTypes.queryConditions.mapFirstCondition() // COMPLETION_PERCENTAGE -> arrayListOf() // PLACE -> QueryCondition.moreOrLess() PLAYERS_COUNT -> QueryCondition.moreOrLess() // TOURNAMENT_RE_BUY_COUNT -> QueryCondition.moreOrLess() - ENTRY_FEE -> Criteria.TournamentFees.queryConditions + ENTRY_FEE -> Criteria.TournamentFees.queryConditions.mapFirstCondition() - TOURNAMENT_NAME -> Criteria.TournamentNames.queryConditions - TOURNAMENT_FEATURE -> Criteria.TournamentFeatures.queryConditions - LOCATION -> Criteria.Locations.queryConditions - BANKROLL -> Criteria.Bankrolls.queryConditions + TOURNAMENT_NAME -> Criteria.TournamentNames.queryConditions.mapFirstCondition() + TOURNAMENT_FEATURE -> Criteria.TournamentFeatures.queryConditions.mapFirstCondition() + LOCATION -> Criteria.Locations.queryConditions.mapFirstCondition() + BANKROLL -> Criteria.Bankrolls.queryConditions.mapFirstCondition() MULTI_TABLING -> QueryCondition.moreOrLess() // NUMBER_OF_PLAYERS -> QueryCondition.moreOrLess() // MULTI_PLAYER -> arrayListOf() From 643940299ea7fa647b74775c10e13075cf51958b Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 26 Apr 2019 18:13:09 +0200 Subject: [PATCH 040/197] Fix Criteria sorting --- .../pokeranalytics/android/model/Criteria.kt | 22 +++++++++---------- .../android/model/filter/Query.kt | 6 +---- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt index 8dfbcec0..0a33cc1a 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt @@ -88,7 +88,6 @@ sealed class Criteria { abstract class RealmCriteria : Criteria() { inline fun comparison(): List { return compare, T>() -// .sorted() } } @@ -111,7 +110,7 @@ sealed class Criteria { else -> null } }.distinct() - return compareList(values = values)//.sorted() + return compareList(values = values) } return listOf() } @@ -200,13 +199,13 @@ sealed class Criteria { realm.where().sort("year", Sort.ASCENDING).findFirst()?.year?.let { for (index in 0..(yearNow - it)) { val yearCondition = QueryCondition.AnyYear().apply { - listOfValues = arrayListOf(yearNow - index) + listOfValues = arrayListOf(it + index) } years.add(Query(yearCondition)) } } realm.close() - years//.sorted() + years } is Blinds -> comparison() else -> throw PokerAnalyticsException.QueryTypeUnhandled @@ -215,28 +214,29 @@ sealed class Criteria { companion object { inline fun , reified T : NameManageable> compare(): List { - val objects = mutableListOf() + val objects = mutableListOf() val realm = Realm.getDefaultInstance() realm.where().findAll().forEach { val condition = (QueryCondition.getInstance() as S).apply { setObject(it) } - val query = Query(condition) - objects.add(query) + objects.add(condition) } + objects.sorted() realm.close() - return objects + return objects.map { Query(it) } } inline fun < reified S : QueryCondition.ListOfValues, T:Any > compareList(values:List): List { - val objects = mutableListOf() + val objects = mutableListOf() values.forEach { val condition =(S::class.java.newInstance()).apply { listOfValues = arrayListOf(it) } - objects.add(Query(condition)) + objects.add(condition) } - return objects + objects.sorted() + return objects.map { Query(it) } } } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt index c8298a16..ffcfdd62 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt @@ -6,11 +6,7 @@ fun List.mapFirstCondition() : List { return this.map { it.conditions.first() } } -class Query : Comparable { - - override fun compareTo(other: QueryCondition): Int { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } +class Query { constructor(vararg elements: QueryCondition) { if (elements.size > 0) { From cf82b55681ae27aa5dd965473c4f3c8feea08cd2 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 26 Apr 2019 18:35:16 +0200 Subject: [PATCH 041/197] Fixing crash + version bump --- app/build.gradle | 2 +- .../pokeranalytics/android/PokerAnalyticsApplication.kt | 4 ++-- .../android/ui/fragment/DataListFragment.kt | 8 ++++++++ .../android/ui/fragment/StatisticDetailsFragment.kt | 8 +++++--- app/src/main/res/values/strings.xml | 2 ++ 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 758e8fb3..d8eda998 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 19 + versionCode 20 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index 26ddf597..5a97d9b0 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -67,9 +67,9 @@ class PokerAnalyticsApplication : Application() { val sessionsCount = realm.where().findAll().size realm.close() - if (sessionsCount < 1) { + if (sessionsCount < 10) { GlobalScope.launch { - FakeDataManager.createFakeSessions(200) + FakeDataManager.createFakeSessions(1) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt index 87c86d33..0e143ef1 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt @@ -6,12 +6,14 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.snackbar.Snackbar import io.realm.RealmObject import io.realm.RealmResults +import io.realm.kotlin.isValid import kotlinx.android.synthetic.main.fragment_data_list.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope @@ -92,6 +94,12 @@ class DataListFragment : PokerAnalyticsFragment(), LiveRowRepresentableDataSourc } override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { + + if (row is Identifiable && !row.isValid()) { + Toast.makeText(requireContext(), R.string.invalid_object, Toast.LENGTH_LONG) + return + } + this.dataType.relatedResultsRepresentable?.let { lastItemClickedPosition = position EditableDataActivity.newInstanceForResult( diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt index 1cf2b32c..0b26c7c1 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt @@ -47,6 +47,7 @@ class StatisticDetailsFragment : PokerAnalyticsFragment() { private lateinit var computableGroup: ComputableGroup private lateinit var graphFragment: GraphFragment private lateinit var selectedReport: Report + private lateinit var aggregationTypes: List private var title: String? = null private var reports: MutableMap = hashMapOf() @@ -99,16 +100,17 @@ class StatisticDetailsFragment : PokerAnalyticsFragment() { fragmentTransaction.add(R.id.graphContainer, graphFragment) fragmentTransaction.commit() - stat.aggregationTypes.firstOrNull()?.let { aggregationType -> + this.aggregationTypes = stat.aggregationTypes + + this.aggregationTypes.firstOrNull()?.let { aggregationType -> reports[aggregationType]?.let { report -> setGraphData(report, aggregationType) } } toolbar.title = this.title ?: stat.localizedTitle(requireContext()) - val aggregationTypes = stat.aggregationTypes - aggregationTypes.forEachIndexed { index, type -> + this.aggregationTypes.forEachIndexed { index, type -> val chip = Chip(requireContext()) chip.id = index chip.text = requireContext().getString(type.resId) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bd118771..e6405524 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -10,6 +10,8 @@ Lines Initial Value Can\'t show because there is less than two values to display! + The object you\'re trying to access is invalid + From bfb08180ad9ff9bc6cdfa45d023e0fb788abf42d Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 26 Apr 2019 19:37:44 +0200 Subject: [PATCH 042/197] Fix crash --- .../net/pokeranalytics/android/ui/fragment/GraphFragment.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt index 47646238..b6cfa111 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt @@ -157,8 +157,10 @@ class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener { barChart.data = barData dataSets.firstOrNull()?.let { - val entry = it.getEntryForIndex(0) - this.chartView?.highlightValue(entry.x, 0) + if (it.entryCount > 0) { + val entry = it.getEntryForIndex(0) + this.chartView?.highlightValue(entry.x, 0) + } } } From f03ec1571d4467501d9532d4c01f7907df059edd Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 29 Apr 2019 09:39:27 +0200 Subject: [PATCH 043/197] bumping versionCode to 21 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index d8eda998..438ad48d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 20 + versionCode 21 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From 01cbd460fd650ac5aa1b97ab9f2215b2ac3b03e2 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 29 Apr 2019 10:32:15 +0200 Subject: [PATCH 044/197] Fixing distribution chart bar colors --- app/build.gradle | 2 +- .../java/net/pokeranalytics/android/calculus/Report.kt | 2 +- .../net/pokeranalytics/android/ui/graph/DataSetFactory.kt | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 758e8fb3..3da9bc75 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 19 + versionCode 22 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt index 1b67154a..cae316c2 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt @@ -441,7 +441,7 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu } } - return DataSetFactory.barDataSetInstance(entries, stat.name, context) + return DataSetFactory.barDataSetInstance(entries, stat.name, context, colors) } val isEmpty: Boolean diff --git a/app/src/main/java/net/pokeranalytics/android/ui/graph/DataSetFactory.kt b/app/src/main/java/net/pokeranalytics/android/ui/graph/DataSetFactory.kt index 4ca91b45..92da7ca9 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/graph/DataSetFactory.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/graph/DataSetFactory.kt @@ -24,10 +24,14 @@ class DataSetFactory { return lineDataSet } - fun barDataSetInstance(entries: List, label: String, context: Context) : BarDataSet { + fun barDataSetInstance(entries: List, label: String, context: Context, colors: MutableList? = null) : BarDataSet { val barDataSet = BarDataSet(entries, label) - barDataSet.color = context.getColor(R.color.chart_bar) + if (colors != null) { + barDataSet.colors = colors + } else { + barDataSet.color = context.getColor(R.color.chart_bar) + } barDataSet.highLightColor = context.getColor(R.color.chart_selected_bar) barDataSet.setDrawValues(false) return barDataSet From 40eeaf5c4ce14a5f980bbb3652ad9a138dc4b51c Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 29 Apr 2019 12:10:02 +0200 Subject: [PATCH 045/197] Refreshes timer when coming back from sleep + stops scrolling to top --- .../android/ui/fragment/SessionFragment.kt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt index 69f5115c..565bfc2c 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt @@ -43,12 +43,21 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate { private val refreshTimer: Runnable = object : Runnable { override fun run() { // Refresh header each 30 seconds - currentSession.updateRowRepresentation() - sessionAdapter.notifyItemChanged(0) + refreshTimer() handler.postDelayed(this, 60000) } } + override fun onResume() { + super.onResume() + this.refreshTimer() + } + + private fun refreshTimer() { + currentSession.updateRowRepresentation() + sessionAdapter.notifyItemChanged(0) + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_session, container, false) } @@ -236,9 +245,9 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate { oldRows.clear() oldRows.addAll(it) - if (scrollToTop) { - recyclerView.smoothScrollToPosition(0) - } +// if (scrollToTop) { +// recyclerView.smoothScrollToPosition(0) +// } } } From 94f412ca33cfe918cde3dce8584109d968116852 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 29 Apr 2019 12:15:03 +0200 Subject: [PATCH 046/197] Improving labels --- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values/strings.xml | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 5fedd9a2..3e3b9d02 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -12,7 +12,7 @@ Adresse - Suggestions + Suggestions de noms %s effacés La date de fin doit être après la date de début Sauvegarder diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e6405524..2ed47a55 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,11 +12,10 @@ Can\'t show because there is less than two values to display! The object you\'re trying to access is invalid - Address - Suggestions + Naming suggestions %s deleted The end date should be after the start date Save From 988e87e697d0145285d6ccd78b3a24fc0fac7264 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 29 Apr 2019 12:38:56 +0200 Subject: [PATCH 047/197] cleanup useless code --- .../android/ui/fragment/StatisticsFragment.kt | 9 --------- 1 file changed, 9 deletions(-) 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 b1d7931b..42eb98ec 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 kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.async import kotlinx.coroutines.launch -import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.ComputableGroup import net.pokeranalytics.android.calculus.Report @@ -58,14 +57,6 @@ class StatisticsFragment : TableReportFragment() { this.statsAdapter?.notifyDataSetChanged() } - override fun initData() { - super.initData() - - this.stringAll = getString(R.string.all) - this.stringCashGame = getString(R.string.cash_game) - this.stringTournament = getString(R.string.tournament) - } - override fun convertReportIntoRepresentables(report: Report): ArrayList { val rows: ArrayList = ArrayList() report.results.forEach { result -> From e26a4f9aa6f27bc1df24889d6c362334f221323e Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 29 Apr 2019 13:07:07 +0200 Subject: [PATCH 048/197] Fixing test build --- .../android/model/CriteriaTest.kt | 35 ++++++++------- .../PerfsInstrumentedUnitTest.kt | 3 +- .../unitTests/StatPerformanceUnitTest.kt | 6 ++- .../unitTests/StatsInstrumentedUnitTest.kt | 25 ++++++----- .../filter/BlindFilterInstrumentedTest.kt | 9 ++-- .../filter/DateFilterInstrumentedUnitTest.kt | 35 ++++++++------- .../SessionFilterInstrumentedUnitTest.kt | 45 ++++++++++--------- 7 files changed, 86 insertions(+), 72 deletions(-) diff --git a/app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt index c0040e5c..1248af55 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt @@ -1,16 +1,10 @@ package net.pokeranalytics.android.model import net.pokeranalytics.android.components.BaseFilterInstrumentedUnitTest -import net.pokeranalytics.android.components.RealmInstrumentedUnitTest import net.pokeranalytics.android.model.filter.QueryCondition -import net.pokeranalytics.android.model.realm.Filter -import net.pokeranalytics.android.model.realm.FilterCondition import net.pokeranalytics.android.model.realm.Session -import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow -import org.junit.Assert +import org.junit.Assert.assertEquals import org.junit.Test - -import org.junit.Assert.* import java.util.* class CriteriaTest : BaseFilterInstrumentedUnitTest() { @@ -39,12 +33,23 @@ class CriteriaTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val years = Criteria.Years.queryConditions as List - println("years = ${years.map { it.getDisplayName() }}") + val yearQueries = Criteria.Years.queryConditions + + assertEquals(16, yearQueries.size) + + val firstYearCondition = yearQueries.first().conditions.first() as QueryCondition.AnyYear + assertEquals(firstValue - 10, firstYearCondition.listOfValues.first()) + + val lastYearCondition = yearQueries.last().conditions.first() as QueryCondition.AnyYear + assertEquals(lastValue, lastYearCondition.listOfValues.first()) + - assertEquals(16, years.size) - assertEquals(firstValue-10, years.first().listOfValues.first()) - assertEquals(lastValue, years.last().listOfValues.first()) +// val years = Criteria.Years.queryConditions as List +// println("years = ${years.map { it.getDisplayName() }}") +// +// assertEquals(16, years.size) +// assertEquals(firstValue-10, years.first().listOfValues.first()) +// assertEquals(lastValue, years.last().listOfValues.first()) } @Test @@ -53,7 +58,7 @@ class CriteriaTest : BaseFilterInstrumentedUnitTest() { val criterias = listOf(Criteria.MonthsOfYear, Criteria.DaysOfWeek) val combined = criterias.combined() combined.forEach { - it.forEach {qc-> + it.conditions.forEach {qc-> println(qc.getDisplayName()) } } @@ -82,9 +87,9 @@ class CriteriaTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val allMonths = Criteria.AllMonthsUpToNow.predicates + val allMonths = Criteria.AllMonthsUpToNow.queries allMonths.forEach { - it.forEach {qc-> + it.conditions.forEach { qc-> println("<<<<< ${qc.getDisplayName()}") } } diff --git a/app/src/androidTest/java/net/pokeranalytics/android/performanceTests/PerfsInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/performanceTests/PerfsInstrumentedUnitTest.kt index 03d39f69..e37cdf53 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/performanceTests/PerfsInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/performanceTests/PerfsInstrumentedUnitTest.kt @@ -8,6 +8,7 @@ import net.pokeranalytics.android.calculus.ComputableGroup import net.pokeranalytics.android.calculus.ComputedResults import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.components.RealmInstrumentedUnitTest +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.realm.ComputableResult import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.SessionSet @@ -54,7 +55,7 @@ class PerfsInstrumentedUnitTest : RealmInstrumentedUnitTest() { Timber.d("sets: ${sets.size}") val stats: List = listOf(Stat.NET_RESULT, Stat.AVERAGE) - val group = ComputableGroup("test", listOf(), stats) + val group = ComputableGroup(Query(), stats) val options = Calculator.Options() options.displayedStats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION) diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatPerformanceUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatPerformanceUnitTest.kt index e7b9773b..7b9f296e 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatPerformanceUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatPerformanceUnitTest.kt @@ -2,6 +2,7 @@ package net.pokeranalytics.android.unitTests import androidx.test.ext.junit.runners.AndroidJUnit4 import net.pokeranalytics.android.components.SessionInstrumentedUnitTest +import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Result import net.pokeranalytics.android.model.realm.Session import org.junit.Test @@ -16,8 +17,11 @@ class StatPerformanceUnitTest : SessionInstrumentedUnitTest() { val realm = mockRealm realm.beginTransaction() + val bankroll = realm.createObject(Bankroll::class.java, "1") + bankroll.live = false + for (index in 0..100) { - Session.testInstance((-2000..2000).random().toDouble()) + Session.testInstance((-2000..2000).random().toDouble(), bankroll = bankroll) println("*** creating $index") } diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatsInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatsInstrumentedUnitTest.kt index 6ae76539..6e56b746 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatsInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatsInstrumentedUnitTest.kt @@ -7,6 +7,7 @@ import net.pokeranalytics.android.calculus.ComputableGroup import net.pokeranalytics.android.calculus.ComputedResults import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.components.SessionInstrumentedUnitTest +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.model.realm.Currency @@ -72,7 +73,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { println(">>>>>> rated net = ${it.ratedNet} ") } - val group = ComputableGroup("test") + val group = ComputableGroup(Query()) val options = Calculator.Options() options.displayedStats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION, @@ -251,7 +252,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { } val stats: List = listOf(Stat.NET_RESULT, Stat.AVERAGE) - val group = ComputableGroup("test", listOf(), stats) + val group = ComputableGroup(Query(), stats) val options = Calculator.Options() options.displayedStats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION) @@ -318,7 +319,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { realm.commitTransaction() val stats: List = listOf(Stat.NET_RESULT, Stat.AVERAGE) - val group = ComputableGroup("test", listOf(), stats) + val group = ComputableGroup(Query(), stats) val options = Calculator.Options() options.displayedStats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION) @@ -401,7 +402,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { realm.commitTransaction() val stats: List = listOf(Stat.NET_RESULT, Stat.AVERAGE) - val group = ComputableGroup("test", listOf(), stats) + val group = ComputableGroup(Query(), stats) val options = Calculator.Options() options.displayedStats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION) @@ -421,7 +422,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { } val stats2: List = listOf(Stat.NET_RESULT, Stat.AVERAGE) - val group2 = ComputableGroup("test", listOf(), stats2) + val group2 = ComputableGroup(Query(), stats2) val results2: ComputedResults = Calculator.compute(realm, group2, options) @@ -546,7 +547,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { } val stats: List = listOf(Stat.NET_RESULT, Stat.AVERAGE) - val group = ComputableGroup("test", listOf(), stats) + val group = ComputableGroup(Query(), stats) val options = Calculator.Options() // options.displayedStats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION) @@ -598,7 +599,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { } val stats: List = listOf(Stat.NET_RESULT) - val group = ComputableGroup("test", listOf(), stats) + val group = ComputableGroup(Query(), stats) val options = Calculator.Options() val results: ComputedResults = Calculator.compute(realm, group, options) @@ -634,7 +635,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { } val stats: List = listOf(Stat.NET_RESULT) - val group = ComputableGroup("test", listOf(), stats) + val group = ComputableGroup(Query(), stats) val options = Calculator.Options() val results: ComputedResults = Calculator.compute(realm, group, options) @@ -652,7 +653,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { } } - val updatedGroup = ComputableGroup("test", listOf(), stats) + val updatedGroup = ComputableGroup(Query(), stats) val updatedResults: ComputedResults = Calculator.compute(realm, updatedGroup, options) val updatedNetResult = updatedResults.computedStat(Stat.NET_RESULT) assertEquals(650.0, updatedNetResult?.value) @@ -683,7 +684,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { s2.endDate = ed2 } - val group = ComputableGroup("", listOf(), listOf()) + val group = ComputableGroup(Query(), listOf()) val options = Calculator.Options(stats = listOf(Stat.DAYS_PLAYED)) val report = Calculator.computeGroups(realm, listOf(group), options) @@ -724,7 +725,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { } - val group = ComputableGroup("test", listOf(QueryCondition.IsCash)) + val group = ComputableGroup(Query(QueryCondition.IsCash)) val options = Calculator.Options() options.displayedStats = listOf(Stat.HOURLY_DURATION) @@ -769,7 +770,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { } - val group = ComputableGroup("test", listOf(QueryCondition.IsCash)) + val group = ComputableGroup(Query(QueryCondition.IsCash)) val options = Calculator.Options() options.displayedStats = listOf(Stat.HOURLY_DURATION) diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/BlindFilterInstrumentedTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/BlindFilterInstrumentedTest.kt index 93cbaac2..f1a85431 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/BlindFilterInstrumentedTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/BlindFilterInstrumentedTest.kt @@ -1,6 +1,7 @@ package net.pokeranalytics.android.unitTests.filter import net.pokeranalytics.android.components.BaseFilterInstrumentedUnitTest +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Filter @@ -51,7 +52,7 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { val filterElement = FilterCondition(filterElementRows = arrayListOf(blind)) filter.updateValueBy(filterElement) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(2, sessions.size) sessions.map { @@ -102,7 +103,7 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { val filterElements = FilterCondition(filterElementRows = arrayListOf(blind1, blind2)) filter.updateValueBy(filterElements) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(2, sessions.size) sessions.map { @@ -150,7 +151,7 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { val filterElement = FilterCondition(filterElementRows = arrayListOf(blind)) filter.updateValueBy(filterElement) println("<<<< ${filter.listOfValues}") - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(1, sessions.size) sessions.map { @@ -202,7 +203,7 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { val filterElement = FilterCondition(filterElementRows = arrayListOf(blind1, blind2)) filter.updateValueBy(filterElement) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(2, sessions.size) sessions.map { diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/DateFilterInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/DateFilterInstrumentedUnitTest.kt index 79ab6ab6..a09ba699 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/DateFilterInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/DateFilterInstrumentedUnitTest.kt @@ -2,6 +2,7 @@ package net.pokeranalytics.android.unitTests.filter import androidx.test.ext.junit.runners.AndroidJUnit4 import net.pokeranalytics.android.components.BaseFilterInstrumentedUnitTest +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.realm.Filter import net.pokeranalytics.android.model.realm.FilterCondition @@ -37,7 +38,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val filterElement = FilterCondition(arrayListOf(filterElementRow)) filter.updateValueBy(filterElement) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -66,7 +67,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val filterElement = FilterCondition(arrayListOf(filterElementRow)) filter.updateValueBy(filterElement) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -94,7 +95,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val filterElement = FilterCondition(arrayListOf(filterElementRow)) filter.updateValueBy(filterElement) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -117,7 +118,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(100.0, true, cal.time) realm.commitTransaction() - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.IsWeekEnd)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.IsWeekEnd)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -142,7 +143,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.IsWeekDay)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.IsWeekDay)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -167,7 +168,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertTrue(realm.where(Session::class.java).findAll().count() == 2) - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.IsToday)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.IsToday)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -192,7 +193,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertTrue(realm.where(Session::class.java).findAll().count() == 2) - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.IsToday)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.IsToday)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -220,7 +221,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertTrue(realm.where(Session::class.java).findAll().count() == 3) - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.WasYesterday)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.WasYesterday)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -247,7 +248,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertTrue(realm.where(Session::class.java).findAll().count() == 3) - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.WasYesterday)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.WasYesterday)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -274,7 +275,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertTrue(realm.where(Session::class.java).findAll().count() == 3) - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.WasTodayAndYesterday)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.WasTodayAndYesterday)) Assert.assertEquals(2, sessions.size) Assert.assertTrue(sessions.containsAll(arrayListOf(s1,s2))) @@ -305,7 +306,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertTrue(realm.where(Session::class.java).findAll().count() == 5) - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.DuringThisYear)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.DuringThisYear)) Assert.assertEquals(3, sessions.size) Assert.assertTrue(sessions.containsAll(arrayListOf(s1,s2, s3))) @@ -337,7 +338,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertTrue(realm.where(Session::class.java).findAll().count() == 5) - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.DuringThisMonth)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.DuringThisMonth)) Assert.assertEquals(2, sessions.size) Assert.assertTrue(sessions.containsAll(arrayListOf(s1,s2))) @@ -361,7 +362,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertTrue(realm.where(Session::class.java).findAll().count() == 2) - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.DuringThisWeek)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.DuringThisWeek)) Assert.assertEquals(1, sessions.size) Assert.assertTrue(sessions.containsAll(arrayListOf(s1))) @@ -387,7 +388,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -415,7 +416,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -444,7 +445,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -473,7 +474,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt index 96a74496..0b1de7a0 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt @@ -3,6 +3,7 @@ package net.pokeranalytics.android.unitTests.filter import androidx.test.ext.junit.runners.AndroidJUnit4 import io.realm.RealmList import net.pokeranalytics.android.components.BaseFilterInstrumentedUnitTest +import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow @@ -24,7 +25,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(100.0, true, Date(), 1) realm.commitTransaction() - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.IsCash)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.IsCash)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -42,7 +43,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(100.0, true, Date(), 1) realm.commitTransaction() - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.IsTournament)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.IsTournament)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { @@ -65,7 +66,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(100.0, true, Date(), 1, b2) realm.commitTransaction() - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.IsLive)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.IsLive)) Assert.assertEquals(1, sessions.size) (sessions[0] as Session).bankroll?.run { @@ -87,7 +88,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(100.0, true, Date(), 1, b2) realm.commitTransaction() - val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.IsOnline)) + val sessions = Filter.queryOn(realm, Query(QueryCondition.IsOnline)) Assert.assertEquals(1, sessions.size) (sessions[0] as Session).bankroll?.run { @@ -112,7 +113,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow.filterSectionRow = FilterSectionRow.BANKROLL filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(1, sessions.size) (sessions[0] as Session).bankroll?.run { @@ -146,7 +147,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow2.filterSectionRow = FilterSectionRow.BANKROLL filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(6, sessions.size) @@ -169,7 +170,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val anyGame = QueryCondition.AnyGame(g2) val fc = FilterCondition(filterElementRows = arrayListOf(anyGame)) - val sessions = Filter.queryOn(realm, arrayListOf(fc.queryCondition)) + val sessions = Filter.queryOn(realm, Query(fc.queryCondition)) Assert.assertEquals(1, sessions.size) (sessions[0] as Session).game?.run { @@ -201,7 +202,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow2.filterSectionRow = FilterSectionRow.GAME val filterCondition = FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2)) val queryCondition = filterCondition.queryCondition - val sessions = Filter.queryOn(realm, arrayListOf(queryCondition)) + val sessions = Filter.queryOn(realm, Query(queryCondition)) Assert.assertEquals(6, sessions.size) @@ -227,7 +228,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow.filterSectionRow = FilterSectionRow.LOCATION filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(1, sessions.size) (sessions[0] as Session).location?.run { @@ -262,7 +263,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(6, sessions.size) @@ -289,7 +290,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow.filterSectionRow = FilterSectionRow.TOURNAMENT_NAME filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(1, sessions.size) (sessions[0] as Session).tournamentName?.run { @@ -322,7 +323,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow.filterSectionRow = FilterSectionRow.TOURNAMENT_NAME filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(6, sessions.size) @@ -360,7 +361,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow3.filterSectionRow = FilterSectionRow.TOURNAMENT_FEATURE filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2, filterElementRow3))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(1, sessions.size) (sessions[0] as Session).run { @@ -397,7 +398,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow4.filterSectionRow = FilterSectionRow.TOURNAMENT_FEATURE filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2, filterElementRow3, filterElementRow4))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(8, sessions.size) } @@ -425,7 +426,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow.filterSectionRow = FilterSectionRow.TOURNAMENT_FEATURE filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) val result = arrayListOf(s1.id, s2.id, s3.id, s4.id) @@ -452,7 +453,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow.filterSectionRow = FilterSectionRow.TABLE_SIZE filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(2, sessions.size) @@ -477,7 +478,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow.filterSectionRow = FilterSectionRow.VALUE filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow))) - val sessions = Filter.queryOn(realm, arrayListOf(filterElementRow)) + val sessions = Filter.queryOn(realm, Query(filterElementRow)) Assert.assertEquals(2, sessions.size) @@ -502,7 +503,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow.filterSectionRow = FilterSectionRow.VALUE filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow))) - val sessions = Filter.queryOn(realm, arrayListOf(filter)) + val sessions = Filter.queryOn(realm, Query(filter)) Assert.assertEquals(3, sessions.size) @@ -532,7 +533,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { filterElementRow2.filterSectionRow = FilterSectionRow.VALUE filterLess.updateValueBy(FilterCondition(arrayListOf(filterElementRow2))) - val sessions = Filter.queryOn(realm, arrayListOf(filterMore, filterLess)) + val sessions = Filter.queryOn(realm, Query(filterMore, filterLess)) Assert.assertEquals(1, sessions.size) @@ -564,7 +565,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() val filterMore = QueryCondition.NumberOfRebuy(QueryCondition.Operator.MORE, 5.0) - val sessions = Filter.queryOn(realm, arrayListOf(filterMore)) + val sessions = Filter.queryOn(realm, Query(filterMore)) Assert.assertEquals(2, sessions.size) @@ -592,7 +593,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() val filterLess = QueryCondition.TournamentFinalPosition(QueryCondition.Operator.LESS, finalPosition = 1) - var sessions = Filter.queryOn(realm, arrayListOf(filterLess)) + var sessions = Filter.queryOn(realm, Query(filterLess)) Assert.assertEquals(1, sessions.size) @@ -603,7 +604,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val filterMore = QueryCondition.TournamentFinalPosition(QueryCondition.Operator.MORE, finalPosition = 10) - sessions = Filter.queryOn(realm, arrayListOf(filterMore)) + sessions = Filter.queryOn(realm, Query(filterMore)) Assert.assertEquals(1, sessions.size) From 8bcfdc8356d6261f996a937f1580606dd0a861eb Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 29 Apr 2019 15:07:05 +0200 Subject: [PATCH 049/197] Fixing conflicts --- app/src/main/res/values/strings.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b8231019..73666f07 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -11,11 +11,6 @@ Initial Value Can\'t show because there is less than two values to display! The object you\'re trying to access is invalid -<<<<<<< HEAD - - -======= ->>>>>>> dev Address Naming suggestions From 30e2b30eb54ff213d48dbbb5d59d5b862f32317f Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 29 Apr 2019 15:16:11 +0200 Subject: [PATCH 050/197] Fixing kmb formatting --- .../android/ui/graph/AxisFormatter.kt | 8 +- .../util/extensions/NumbersExtension.kt | 91 ++++++++++--------- .../pokeranalytics/android/BasicUnitTest.kt | 12 ++- 3 files changed, 57 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/graph/AxisFormatter.kt b/app/src/main/java/net/pokeranalytics/android/ui/graph/AxisFormatter.kt index 8b9673c9..b9d21687 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/graph/AxisFormatter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/graph/AxisFormatter.kt @@ -8,11 +8,11 @@ import kotlin.math.roundToInt class LargeNumberFormatter : ValueFormatter() { override fun getFormattedValue(value: Float): String { - return value.kmbFormatted + return value.kmbFormatted() } override fun getAxisLabel(value: Float, axis: AxisBase?): String { - return value.roundToInt().kmbFormatted + return value.roundToInt().kmbFormatted() } } @@ -20,11 +20,11 @@ class LargeNumberFormatter : ValueFormatter() { class HourFormatter : ValueFormatter() { override fun getFormattedValue(value: Float): String { - return value.kmbFormatted + "H" + return value.kmbFormatted() + "H" } override fun getAxisLabel(value: Float, axis: AxisBase?): String { - val test = value.kmbFormatted + "H" + val test = value.kmbFormatted() + "H" return test } diff --git a/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt b/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt index 9566e07a..c2578945 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt @@ -7,70 +7,71 @@ import java.text.DecimalFormat import java.text.NumberFormat import java.util.* -val Number.kmbFormatted: String - get() { - var thousandsExponent = 0 - var v = this.toDouble() - while (abs(v) >= 10000 && thousandsExponent < 3) { +fun Number.kmbFormatted(threshold: Double = 10000.0): String { + var thousandsExponent = 0 + var v = this.toDouble() + if (abs(v) >= threshold) { + while (abs(v) >= 1000 && thousandsExponent < 3) { v /= 1000 thousandsExponent++ } + } - val unit = when(thousandsExponent) { - 0 -> "" - 1 -> "K" - 2 -> "M" - 3 -> "B" - else -> "B+" // shouldn't happen - } - - val formatter = NumberFormat.getInstance() - return formatter.format(v) + unit + val unit = when (thousandsExponent) { + 0 -> "" + 1 -> "K" + 2 -> "M" + 3 -> "B" + else -> "B+" // shouldn't happen } + val formatter = NumberFormat.getInstance() + return formatter.format(v) + unit +} + // Double fun Double.round(): String { - val formatter = DecimalFormat("##.##") - return formatter.format(this) + val formatter = DecimalFormat("##.##") + return formatter.format(this) } fun Double.formatted(): String { - val format = NumberFormat.getNumberInstance() - format.maximumFractionDigits = 2 - format.minimumFractionDigits = 0 - return format.format(this) + val format = NumberFormat.getNumberInstance() + format.maximumFractionDigits = 2 + format.minimumFractionDigits = 0 + return format.format(this) } fun Double.toCurrency(currency: Currency? = null): String { - val currencyFormatter = NumberFormat.getCurrencyInstance() + val currencyFormatter = NumberFormat.getCurrencyInstance() currency?.let { currencyFormatter.currency = currency } - currencyFormatter.maximumFractionDigits = 2 - currencyFormatter.minimumFractionDigits = 0 - return currencyFormatter.format(this) + currencyFormatter.maximumFractionDigits = 2 + currencyFormatter.minimumFractionDigits = 0 + return currencyFormatter.format(this) } fun Double.toRate(): String { - val currencyFormatter = NumberFormat.getInstance() - currencyFormatter.minimumFractionDigits = 0 - currencyFormatter.maximumFractionDigits = 6 - return currencyFormatter.format(this) + val currencyFormatter = NumberFormat.getInstance() + currencyFormatter.minimumFractionDigits = 0 + currencyFormatter.maximumFractionDigits = 6 + return currencyFormatter.format(this) } -fun Double.formattedHourlyDuration() : String { - return (this * 1000 * 3600).toLong().toMinutes() +fun Double.formattedHourlyDuration(): String { + return (this * 1000 * 3600).toLong().toMinutes() } // Return the time from minutes to hours:minutes -fun Int.toMinutes(context: Context) : String { - val hours = this / 60 - val minutesLeft = this % 60 - var duration = "" +fun Int.toMinutes(context: Context): String { + val hours = this / 60 + val minutesLeft = this % 60 + var duration = "" if (hours < 1) { duration += "$minutesLeft ${context.getString(if (minutesLeft > 1) R.string.mins else R.string.min)}" @@ -80,17 +81,17 @@ fun Int.toMinutes(context: Context) : String { duration += if (minutesLeft < 10) "0$minutesLeft" else minutesLeft.toString() } - return duration + return duration } // Return the time from milliseconds to hours:minutes -fun Long.toMinutes() : String { - val totalMinutes = this / (1000 * 60) - val hours = totalMinutes / 60 - val minutesLeft = totalMinutes % 60 - var duration = "" - duration += hours.toString() - duration += ":" - duration += if (minutesLeft < 10) "0$minutesLeft" else minutesLeft.toString() - return duration +fun Long.toMinutes(): String { + val totalMinutes = this / (1000 * 60) + val hours = totalMinutes / 60 + val minutesLeft = totalMinutes % 60 + var duration = "" + duration += hours.toString() + duration += ":" + duration += if (minutesLeft < 10) "0$minutesLeft" else minutesLeft.toString() + return duration } \ No newline at end of file diff --git a/app/src/test/java/net/pokeranalytics/android/BasicUnitTest.kt b/app/src/test/java/net/pokeranalytics/android/BasicUnitTest.kt index 0a2424f2..3ab9079b 100644 --- a/app/src/test/java/net/pokeranalytics/android/BasicUnitTest.kt +++ b/app/src/test/java/net/pokeranalytics/android/BasicUnitTest.kt @@ -19,13 +19,15 @@ class BasicUnitTest : RealmUnitTest() { val n3 = n2 * n2 // 1M val n4 = n3 * n2 // 1B - val s1 = n1.kmbFormatted - val s2 = n2.kmbFormatted - val s3 = n3.kmbFormatted - val s4 = n4.kmbFormatted + val s1 = n1.kmbFormatted() + val s2 = n2.kmbFormatted() + val s2b = n2.kmbFormatted(1000.0) + val s3 = n3.kmbFormatted() + val s4 = n4.kmbFormatted() Assert.assertEquals("100", s1) - Assert.assertEquals("1K", s2) +// Assert.assertEquals("1/e000", s2) // weird error Expected :1 000, Actual :1 000 + Assert.assertEquals("1K", s2b) Assert.assertEquals("1M", s3) Assert.assertEquals("1B", s4) From a39db350a547a67a5eba7478622c9d4786aff166 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Mon, 29 Apr 2019 15:49:35 +0200 Subject: [PATCH 051/197] fix issue with unit test --- .../main/java/net/pokeranalytics/android/model/realm/Session.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 7aa0c342..b0dd3b95 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -77,7 +77,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat AnyTournamentType::class.java -> "tournamentType" AnyBlind::class.java -> "blinds" NumberOfTable::class.java -> "numberOfTable" - NetAmount::class.java -> "computableResults.ratedNet" + NetAmountWon::class.java, NetAmountLost::class.java -> "computableResults.ratedNet" NumberOfRebuy::class.java -> "result.numberOfRebuy" TournamentNumberOfPlayer::class.java -> "result.tournamentNumberOfPlayers" TournamentFinalPosition::class.java -> "result.tournamentFinalPosition" From 31902bd10e64aa3449b2b1fd1bc23e0cb9b8069a Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 29 Apr 2019 15:56:10 +0200 Subject: [PATCH 052/197] Fixing test issue --- .../android/components/SessionInstrumentedUnitTest.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/androidTest/java/net/pokeranalytics/android/components/SessionInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/components/SessionInstrumentedUnitTest.kt index fd6cf759..ed063e5e 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/components/SessionInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/components/SessionInstrumentedUnitTest.kt @@ -1,12 +1,9 @@ package net.pokeranalytics.android.components -import androidx.test.ext.junit.runners.AndroidJUnit4 import io.realm.RealmList import net.pokeranalytics.android.model.realm.* -import org.junit.runner.RunWith import java.util.* -@RunWith(AndroidJUnit4::class) open class SessionInstrumentedUnitTest : RealmInstrumentedUnitTest() { // convenience extension From 846444b80a34738f434df0f13d4fc9161e967b73 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 29 Apr 2019 16:06:23 +0200 Subject: [PATCH 053/197] Remove fake data creation --- .../net/pokeranalytics/android/PokerAnalyticsApplication.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index 17166326..1ba206d1 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -52,7 +52,7 @@ class PokerAnalyticsApplication : Application() { if (BuildConfig.DEBUG) { Timber.d("UserPreferences.defaultCurrency: ${UserDefaults.currency.symbol}") - this.createFakeSessions() +// this.createFakeSessions() } Patcher.patchBreaks() From 71cc891e81e4fa4c4efc6b07f4b2c0d075f2b6a3 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 29 Apr 2019 18:07:39 +0200 Subject: [PATCH 054/197] Fix possible crash when no bankroll is set --- .../pokeranalytics/android/ui/fragment/SessionFragment.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt index 565bfc2c..05c5d691 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt @@ -122,7 +122,12 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate { override fun onRowValueChanged(value: Any?, row: RowRepresentable) { sessionHasBeenCustomized = true - currentSession.updateValue(value, row) + try { + currentSession.updateValue(value, row) + } catch (e: IllegalStateException) { + Toast.makeText(context, e.message, Toast.LENGTH_LONG).show() + return + } sessionAdapter.refreshRow(row) when (row) { SessionRow.CASHED_OUT, SessionRow.PRIZE, SessionRow.NET_RESULT, SessionRow.BUY_IN, SessionRow.TIPS, From 0c5af6d8d272587152ec0622442846bbddc2dbb6 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 30 Apr 2019 10:39:25 +0200 Subject: [PATCH 055/197] Avoid crash when chipgroup is unchecked --- .../android/ui/fragment/StatisticDetailsFragment.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt index e142d75b..962a29de 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt @@ -120,11 +120,18 @@ class StatisticDetailsFragment : PokerAnalyticsFragment() { } this.chipGroup.isVisible = displayAggregationChoices + this.chipGroup.setSingleSelection(true) this.chipGroup.check(0) this.chipGroup.setOnCheckedChangeListener(object : ChipGroupExtension.SingleSelectionOnCheckedListener() { override fun onCheckedChanged(group: ChipGroup, checkedId: Int) { super.onCheckedChanged(group, checkedId) + + @SuppressWarnings + if (checkedId < 0) { // when unchecked, checkedId returns -1, causing a crash + return + } + val aggregationType = aggregationTypes[checkedId] when (aggregationType) { From 64bcb6fe880fe6ae121763fe85bb3921ba332725 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 30 Apr 2019 10:41:19 +0200 Subject: [PATCH 056/197] bumping version to 25 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 3da9bc75..c54b385d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 22 + versionCode 25 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From 4b4cac69c44701fa23c2fb57746644c722530090 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 7 May 2019 11:00:05 +0200 Subject: [PATCH 057/197] Add Billing to manifest + version bumping to 26 to add subscription in GP console --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c54b385d..d3cfd4cd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 25 + versionCode 26 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8c2989ed..ce174f66 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + Date: Wed, 8 May 2019 14:44:14 +0200 Subject: [PATCH 058/197] Fixes potential issue leaving ComputableResults alone --- .../pokeranalytics/android/model/realm/Session.kt | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index b0dd3b95..1cca7337 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -559,16 +559,14 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat */ fun cleanup() { + // Updates the timeline this.sessionSet?.let { - - // Updates the timeline SessionSetManager.removeFromTimeline(this) - - // cleanup unnecessary related objects - this.result?.deleteFromRealm() - this.computableResults?.deleteAllFromRealm() - } + // cleanup unnecessary related objects + this.result?.deleteFromRealm() + this.computableResults?.deleteAllFromRealm() + } @Ignore From 3fdcf472c6e8ea8cd85c7fb1addff7ff925427ca Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 8 May 2019 15:28:14 +0200 Subject: [PATCH 059/197] Patches lone ComputableResult --- .../android/PokerAnalyticsApplication.kt | 2 +- .../android/model/migrations/Patcher.kt | 20 ++++++++++++---- .../android/util/Preferences.kt | 23 +++++++++++++++---- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index 1ba206d1..96374a08 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -55,7 +55,7 @@ class PokerAnalyticsApplication : Application() { // this.createFakeSessions() } - Patcher.patchBreaks() + Patcher.patchBreaks(applicationContext) } /** diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt index 7ebd0bce..bb4550a8 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt @@ -1,18 +1,17 @@ package net.pokeranalytics.android.model.migrations +import android.content.Context import io.realm.Realm import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition -import net.pokeranalytics.android.model.realm.Filter -import net.pokeranalytics.android.model.realm.Result -import net.pokeranalytics.android.model.realm.Session -import net.pokeranalytics.android.model.realm.SessionSet +import net.pokeranalytics.android.model.realm.* +import net.pokeranalytics.android.util.Preferences class Patcher { companion object { - fun patchBreaks() { + fun patchBreaks(context: Context) { val realm = Realm.getDefaultInstance() val sets = realm.where(SessionSet::class.java).findAll() @@ -30,6 +29,17 @@ class Patcher { it.computeNumberOfRebuy() } } + + if (!Preferences.getBoolean(Preferences.DBPatch.LONE_COMPUTABLE_RESULTS, context)) { + + // patch for https://console.firebase.google.com/project/poker-analytics-97998/crashlytics/app/android:net.pokeranalytics.android/issues/5cd2c884f8b88c29635caa16 + val loneComputableResults = realm.where(ComputableResult::class.java).isNull("session").findAll() + realm.executeTransaction { + loneComputableResults.deleteAllFromRealm() + } + Preferences.setBoolean(Preferences.DBPatch.LONE_COMPUTABLE_RESULTS, true, context) + } + realm.close() } diff --git a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt index cfc53b7f..def5f091 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt @@ -6,7 +6,20 @@ import java.util.* class Preferences { - enum class Keys(var identifier: String) { + interface PreferenceKey { + var identifier: String + } + + enum class DBPatch(var key: String) : PreferenceKey { + LONE_COMPUTABLE_RESULTS("loneComputableResult"); + + override var identifier: String = "" + get() { + return "dbpatch." + this.key + } + } + + enum class Keys(override var identifier: String) : PreferenceKey { CURRENCY_CODE("CurrencyCode"), LOCALE_CODE("LocaleCode"), FIRST_LAUNCH("firstLaunch"), @@ -16,26 +29,26 @@ class Preferences { companion object { - fun setString(key: Keys, value: String, context: Context) { + fun setString(key: PreferenceKey, value: String, context: Context) { val preferences = PreferenceManager.getDefaultSharedPreferences(context) val editor = preferences.edit() editor.putString(key.identifier, value) editor.apply() } - fun getString(key: Keys, context: Context) : String? { + fun getString(key: PreferenceKey, context: Context) : String? { val preferences = PreferenceManager.getDefaultSharedPreferences(context) return preferences.getString(key.identifier, null) } - fun setBoolean(key: Keys, value: Boolean, context: Context) { + fun setBoolean(key: PreferenceKey, value: Boolean, context: Context) { val preferences = PreferenceManager.getDefaultSharedPreferences(context) val editor = preferences.edit() editor.putBoolean(key.identifier, value) editor.apply() } - fun getBoolean(key: Keys, context: Context, defaultValue: Boolean? = false) : Boolean { + fun getBoolean(key: PreferenceKey, context: Context, defaultValue: Boolean? = false) : Boolean { val preferences = PreferenceManager.getDefaultSharedPreferences(context) return preferences.getBoolean(key.identifier, defaultValue ?: false) } From 1025278613dff39970431fa853be28a3968f9c06 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 8 May 2019 15:29:04 +0200 Subject: [PATCH 060/197] Bumps versionCode to 27 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index d3cfd4cd..e30f903c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,7 +28,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 26 + versionCode 27 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From dec90dab297eb371fc2b55f1741ef233becb49b1 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 4 Jun 2019 16:15:21 +0200 Subject: [PATCH 061/197] Fixes build issues following the merge --- .../pokeranalytics/android/model/migrations/Patcher.kt | 10 ---------- .../ui/fragment/report/ProgressReportFragment.kt | 6 ++---- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt index d87eb77e..8819d996 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt @@ -41,16 +41,6 @@ class Patcher { } } - if (!Preferences.getBoolean(Preferences.DBPatch.LONE_COMPUTABLE_RESULTS, context)) { - - // patch for https://console.firebase.google.com/project/poker-analytics-97998/crashlytics/app/android:net.pokeranalytics.android/issues/5cd2c884f8b88c29635caa16 - val loneComputableResults = realm.where(ComputableResult::class.java).isNull("session").findAll() - realm.executeTransaction { - loneComputableResults.deleteAllFromRealm() - } - Preferences.setBoolean(Preferences.DBPatch.LONE_COMPUTABLE_RESULTS, true, context) - } - realm.close() } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ProgressReportFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ProgressReportFragment.kt index c256db17..b7649be5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ProgressReportFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ProgressReportFragment.kt @@ -87,9 +87,7 @@ class ProgressReportFragment : AbstractReportFragment() { fragmentTransaction?.add(R.id.graphContainer, graphFragment) fragmentTransaction?.commit() - this.aggregationTypes = stat.aggregationTypes - - this.aggregationTypes.firstOrNull()?.let { aggregationType -> + stat.aggregationTypes.firstOrNull()?.let { aggregationType -> reports[aggregationType]?.let { report -> setGraphData(report, aggregationType) } @@ -97,7 +95,7 @@ class ProgressReportFragment : AbstractReportFragment() { val aggregationTypes = stat.aggregationTypes - this.aggregationTypes.forEachIndexed { index, type -> + aggregationTypes.forEachIndexed { index, type -> val chip = Chip(requireContext()) chip.id = index chip.text = requireContext().getString(type.resId) From dc22bc70106938119266ded4d7d826506b0bd825 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Tue, 4 Jun 2019 16:48:38 +0200 Subject: [PATCH 062/197] fix issue with realm migration --- .../android/model/migrations/PokerAnalyticsMigration.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index eccf538f..996f6da0 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -131,7 +131,7 @@ class PokerAnalyticsMigration : RealmMigration { schema.get("ReportSetup")?.let { it.addRealmListField("statIds", Int::class.java).setNullable("statIds", true) - it.addRealmListField("criteriaCustomFieldIds", String::class.java).setNullable("criteriaCustomFieldIds", true) + it.addRealmListField("criteriaCustomFieldIds", String::class.java) it.addRealmListField("criteriaIds", Int::class.java).setNullable("criteriaIds", true) it.removeField("filters") schema.get("Filter")?.let { filterSchema -> From 20b0cc50657247fc265d8c77abb74001ec6f5de8 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 5 Jun 2019 12:26:26 +0200 Subject: [PATCH 063/197] Fixes translation --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8d7265fb..2e0726ec 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -156,7 +156,7 @@ Results will be filtered on cash games Cashed out You need to name the custom field - This item is linked to one or more sessions. Please confirm the delete of this item. + This item is linked to one or more sessions. Please confirm the deletion of this item. Confirmation The chart cannot be exported and shared, please contact the support team Chart From 43fd63f5264f6d4a1e1b69a04be30e7cc9f84d1e Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 5 Jun 2019 16:03:38 +0200 Subject: [PATCH 064/197] Fixes issue with custom field entry deletion --- .../android/model/interfaces/Manageable.kt | 2 +- .../android/model/realm/CustomField.kt | 27 +++++++++---------- .../android/model/realm/CustomFieldEntry.kt | 4 +-- .../components/DeletableItemFragment.kt | 2 +- .../fragment/data/CustomFieldDataFragment.kt | 13 ++++++--- 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt index 74097255..05624c3a 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt @@ -125,6 +125,6 @@ interface Deletable : Identifiable { /** * A method to override if we need to delete linked objects or other stuff */ - fun deleteDependencies() {} + fun deleteDependencies(realm: Realm) {} } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt index 9acf817e..694ef77d 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt @@ -59,7 +59,8 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa var type: Int = Type.LIST.uniqueIdentifier set(value) { if (field == Type.LIST.uniqueIdentifier && value != Type.LIST.uniqueIdentifier) { - this.removeListEntries() + this.entriesToDelete.addAll(this.entries) + this.entries.clear() } field = value @@ -146,7 +147,7 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa } override fun isValidForDelete(realm: Realm): Boolean { - val sessions = realm.where().contains("customFieldEntries.customField.id", id).findAll() + val sessions = realm.where().contains("customFieldEntries.customFields.id", id).findAll() return sessions.isEmpty() } @@ -163,7 +164,7 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa } } - override fun deleteDependencies() { + override fun deleteDependencies(realm: Realm) { if (isValid) { val entries = realm.where().equalTo("customField.id", id).findAll() entries.deleteAllFromRealm() @@ -257,26 +258,24 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa * Delete an entry */ fun deleteEntry(entry: CustomFieldEntry) { - entries.remove(entry) entriesToDelete.add(entry) + entries.remove(entry) + sortEntries() updateRowRepresentation() } - private fun removeListEntries() { + fun cleanupEntries() { // called when saving the custom field - this.entriesToDelete.addAll(entries) - this.entries.clear() + val realm = Realm.getDefaultInstance() - if (realm != null) { - realm.executeTransaction { - this.entriesToDelete.forEach { - if (it.isManaged) { - it.deleteFromRealm() - } - } + realm.executeTransaction { + this.entriesToDelete.forEach { // entries are out of realm + realm.where().equalTo("id", it.id).findFirst()?.deleteFromRealm() } } + realm.close() + this.entriesToDelete.clear() } /** diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt index f6703266..f4716084 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt @@ -110,9 +110,9 @@ open class CustomFieldEntry : RealmObject(), NameManageable, RowRepresentable { return R.string.cf_entry_delete_popup_message } - override fun deleteDependencies() { + override fun deleteDependencies(realm: Realm) { if (isValid) { - val entries = realm.where().equalTo("customField.id", id).findAll() + val entries = realm.where().contains("customFieldEntries.id", id).findAll() entries.deleteAllFromRealm() } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt index 232a7d46..71cea8c1 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt @@ -88,7 +88,7 @@ abstract class DeletableItemFragment : RealmFragment() { deletedItem = getRealm().copyFromRealm(itemToDelete) lastDeletedItemPosition = itemPosition getRealm().executeTransaction { - itemToDelete.deleteDependencies() + itemToDelete.deleteDependencies(it) itemToDelete.deleteFromRealm() } itemHasBeenReInserted = false diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt index 768b8088..53fae129 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt @@ -187,10 +187,10 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa customField.deleteEntry(row) rowRepresentableAdapter.notifyDataSetChanged() }) - return + } else { + customField.deleteEntry(row) + rowRepresentableAdapter.notifyDataSetChanged() } - customField.deleteEntry(row) - rowRepresentableAdapter.notifyDataSetChanged() } } } @@ -271,4 +271,11 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa } } + override fun onDataSaved() { + super.onDataSaved() + + this.customField.cleanupEntries() + + } + } \ No newline at end of file From 25d2fdac15dfcf462cbe4fa1b46ba079f96b559f Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 5 Jun 2019 16:14:23 +0200 Subject: [PATCH 065/197] fixes issue when deleting a custom field --- .../net/pokeranalytics/android/model/realm/CustomField.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt index 694ef77d..2b03ba11 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt @@ -147,8 +147,9 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa } override fun isValidForDelete(realm: Realm): Boolean { - val sessions = realm.where().contains("customFieldEntries.customFields.id", id).findAll() - return sessions.isEmpty() + return true +// val sessions = realm.where().contains("customFieldEntries.customFields.id", id).findAll() +// return sessions.isEmpty() } override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int { @@ -166,7 +167,7 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa override fun deleteDependencies(realm: Realm) { if (isValid) { - val entries = realm.where().equalTo("customField.id", id).findAll() + val entries = realm.where().equalTo("customFields.id", id).findAll() entries.deleteAllFromRealm() } } From 78c9ec2c516fde73cc1152c231986380a2c91440 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 5 Jun 2019 18:35:11 +0200 Subject: [PATCH 066/197] code cleanup --- .../CustomFieldFilterInstrumentedUnitTest.kt | 56 ++++++++++--------- .../android/model/filter/Query.kt | 3 +- .../android/model/filter/QueryCondition.kt | 1 + .../android/model/realm/Filter.kt | 16 ++++-- 4 files changed, 43 insertions(+), 33 deletions(-) diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/CustomFieldFilterInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/CustomFieldFilterInstrumentedUnitTest.kt index f3880227..f3acfcbc 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/CustomFieldFilterInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/CustomFieldFilterInstrumentedUnitTest.kt @@ -51,35 +51,41 @@ class CustomFieldFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { @Test fun testCustomFieldAmountFilter() { - val realm = this.mockRealm - realm.beginTransaction() - - val cf1 = CustomField() - cf1.id = "1234" - cf1.type = CustomField.Type.AMOUNT.ordinal - - - val cfe1 = CustomFieldEntry() - cfe1.id = "999" - cf1.entries.add(cfe1) - cfe1.numericValue = 30.0 - - val cfe2 = CustomFieldEntry() - cfe2.id = "888" - cf1.entries.add(cfe2) - cfe2.numericValue = 100.0 + val cf1Id = "1234" + var s2Id = "" - val s1 = Session.testInstance(100.0, false, Date(), 1) - s1.customFieldEntries.add(cfe1) - val s2 = Session.testInstance(100.0, true, Date(), 1) - s2.customFieldEntries.add(cfe2) - realm.commitTransaction() + val realm = this.mockRealm + realm.executeTransaction { + + val cf1 = CustomField() + cf1.id = cf1Id + cf1.type = CustomField.Type.AMOUNT.ordinal + + val cfe1 = CustomFieldEntry() + cfe1.id = "999" + cf1.entries.add(cfe1) + cfe1.numericValue = 30.0 + + val cfe2 = CustomFieldEntry() + cfe2.id = "888" + cf1.entries.add(cfe2) + cfe2.numericValue = 100.0 + + val s1 = Session.testInstance(100.0, false, Date(), 1) + s1.customFieldEntries.add(cfe1) + val s2 = Session.testInstance(100.0, true, Date(), 1) + s2.customFieldEntries.add(cfe2) + s2Id = s2.id + } - val sessions = Filter.queryOn(realm, Query(QueryCondition.CustomFieldNumberQuery(cf1.id, 100.0))) + val condition = QueryCondition.CustomFieldNumberQuery(cf1Id, 100.0) + val sessions = Filter.queryOn(realm, Query(condition)) Assert.assertEquals(1, sessions.size) - sessions[0]?.run { - Assert.assertEquals(s2.id, (this).id) + sessions.first()?.run { + Assert.assertEquals(s2Id, this.id) } + } + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt index ef2f0b2b..e5caffa0 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt @@ -2,7 +2,6 @@ package net.pokeranalytics.android.model.filter import android.content.Context import io.realm.RealmQuery -import io.realm.kotlin.where import net.pokeranalytics.android.R import net.pokeranalytics.android.util.NULL_TEXT @@ -77,7 +76,7 @@ class Query { } } - //println("<<<<<< ${realmQuery}") + println("<<<<<< ${realmQuery.description}") val queryLast = this.conditions.filter { it is QueryCondition.Last }.firstOrNull() diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt index 9a13f72a..2907fd06 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt @@ -668,6 +668,7 @@ sealed class QueryCondition : FilterElementRow { realmQuery: RealmQuery, otherQueryCondition: QueryCondition? = null ): RealmQuery { + val fieldName = FilterHelper.fieldNameForQueryType(this::class.java) if (BuildConfig.DEBUG) { fieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt index 3f1e481b..3b1c1c16 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt @@ -1,7 +1,10 @@ package net.pokeranalytics.android.model.realm import android.content.Context -import io.realm.* +import io.realm.Realm +import io.realm.RealmList +import io.realm.RealmObject +import io.realm.RealmResults import io.realm.annotations.PrimaryKey import io.realm.kotlin.where import net.pokeranalytics.android.R @@ -41,13 +44,14 @@ open class Filter : RealmObject(), RowRepresentable, Identifiable, Deletable, Co } inline fun queryOn(realm: Realm, query: Query, sortField: String? = null): RealmResults { - val realmQuery = realm.where() + val rootQuery = realm.where() + var realmQuery = query.queryWith(rootQuery) sortField?.let { - return query.queryWith(realmQuery).sort(it).findAll() - } ?: run { - return query.queryWith(realmQuery).findAll() + realmQuery = realmQuery.sort(it) } - } + val desc = realmQuery.description + return realmQuery.findAll() + } } @PrimaryKey From 420dfa52aeda0aedefdc1c2120b7b78dc686c345 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 5 Jun 2019 19:45:52 +0200 Subject: [PATCH 067/197] fixing custom field tests --- .../CustomFieldFilterInstrumentedUnitTest.kt | 26 ++++++++----------- .../android/model/filter/QueryCondition.kt | 2 +- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/CustomFieldFilterInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/CustomFieldFilterInstrumentedUnitTest.kt index f3acfcbc..8f732f0e 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/CustomFieldFilterInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/CustomFieldFilterInstrumentedUnitTest.kt @@ -22,12 +22,11 @@ class CustomFieldFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val realm = this.mockRealm realm.beginTransaction() - val cf1 = CustomField() - cf1.id = "1" + val cf1 = realm.createObject(CustomField::class.java, "1") cf1.type = CustomField.Type.LIST.ordinal - val cfe1 = CustomFieldEntry() - val cfe2 = CustomFieldEntry() + val cfe1 = realm.createObject(CustomFieldEntry::class.java, "9") + val cfe2 = realm.createObject(CustomFieldEntry::class.java, "8") cfe1.value = "super" cfe2.value = "nul" @@ -51,24 +50,21 @@ class CustomFieldFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { @Test fun testCustomFieldAmountFilter() { - val cf1Id = "1234" + val cfId = "1234" var s2Id = "" val realm = this.mockRealm realm.executeTransaction { - val cf1 = CustomField() - cf1.id = cf1Id - cf1.type = CustomField.Type.AMOUNT.ordinal + val cf = realm.createObject(CustomField::class.java, cfId) + cf.type = CustomField.Type.AMOUNT.ordinal - val cfe1 = CustomFieldEntry() - cfe1.id = "999" - cf1.entries.add(cfe1) + val cfe1 = realm.createObject(CustomFieldEntry::class.java, "999") + cf.entries.add(cfe1) cfe1.numericValue = 30.0 - val cfe2 = CustomFieldEntry() - cfe2.id = "888" - cf1.entries.add(cfe2) + val cfe2 = realm.createObject(CustomFieldEntry::class.java, "888") + cf.entries.add(cfe2) cfe2.numericValue = 100.0 val s1 = Session.testInstance(100.0, false, Date(), 1) @@ -78,7 +74,7 @@ class CustomFieldFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { s2Id = s2.id } - val condition = QueryCondition.CustomFieldNumberQuery(cf1Id, 100.0) + val condition = QueryCondition.CustomFieldNumberQuery(cfId, 100.0) val sessions = Filter.queryOn(realm, Query(condition)) Assert.assertEquals(1, sessions.size) diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt index 2907fd06..06e34c97 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt @@ -645,7 +645,7 @@ sealed class QueryCondition : FilterElementRow { constructor(customFieldEntry: CustomFieldEntry) : this() { this.setObject(customFieldEntry) - this.customFieldId = customFieldEntry.customFields?.firstOrNull()?.id + this.customFieldId = customFieldEntry.customField?.id ?: throw PokerAnalyticsException.QueryValueMapUnexpectedValue } From c94b42abe8930f90f9bc0679e0efadc0119f9849 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 6 Jun 2019 12:33:43 +0200 Subject: [PATCH 068/197] Add filter name edition --- app/src/main/AndroidManifest.xml | 5 + .../android/model/realm/Filter.kt | 204 +++++++++++------- .../ui/activity/FiltersListActivity.kt | 58 +++++ .../android/ui/fragment/DataListFragment.kt | 4 +- .../android/ui/fragment/FiltersFragment.kt | 4 +- .../ui/fragment/FiltersListFragment.kt | 122 +++++++++++ .../BottomSheetDoubleEditTextFragment.kt | 1 - .../BottomSheetEditTextFragment.kt | 1 - .../bottomsheet/BottomSheetFragment.kt | 2 +- .../BottomSheetNumericTextFragment.kt | 1 - .../android/ui/interfaces/FilterHandler.kt | 114 +++++----- .../main/res/layout/activity_filters_list.xml | 15 ++ 12 files changed, 383 insertions(+), 148 deletions(-) create mode 100644 app/src/main/java/net/pokeranalytics/android/ui/activity/FiltersListActivity.kt create mode 100644 app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersListFragment.kt create mode 100644 app/src/main/res/layout/activity_filters_list.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c296be62..8cf3f769 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -109,6 +109,11 @@ android:launchMode="singleTop" android:screenOrientation="portrait" /> + + ().equalTo("id", filterId).findFirst() } - inline fun queryOn(realm: Realm, query: Query, sortField: String? = null): RealmResults { - val realmQuery = realm.where() - sortField?.let { - return query.queryWith(realmQuery).sort(it).findAll() - } ?: run { - return query.queryWith(realmQuery).findAll() - } - } - } + inline fun queryOn(realm: Realm, query: Query, sortField: String? = null): RealmResults { + val realmQuery = realm.where() + sortField?.let { + return query.queryWith(realmQuery).sort(it).findAll() + } ?: run { + return query.queryWith(realmQuery).findAll() + } + } + } + + override val viewType: Int + get() = RowViewType.TITLE_VALUE_ACTION.ordinal + override val imageRes: Int? + get() = R.drawable.ic_outline_settings + override val imageTint: Int? + get() = R.color.green + override val imageClickable: Boolean? + get() = true + @PrimaryKey - override var id = UUID.randomUUID().toString() + override var id = UUID.randomUUID().toString() // the queryWith name var name: String = "" - get() { - if (field.isEmpty()) { - return this.query.defaultName - } - return field - } + get() { + if (field.isEmpty()) { + return this.query.defaultName + } + return field + } - override var useCount: Int = 0 + override var useCount: Int = 0 var filterConditions: RealmList = RealmList() private set - private var filterableTypeUniqueIdentifier: Int? = null + private var filterableTypeUniqueIdentifier: Int? = null - val filterableType: FilterableType - get() { - this.filterableTypeUniqueIdentifier?.let { - return FilterableType.valueByIdentifier(it) - } - return FilterableType.ALL - } + val filterableType: FilterableType + get() { + this.filterableTypeUniqueIdentifier?.let { + return FilterableType.valueByIdentifier(it) + } + return FilterableType.ALL + } fun createOrUpdateFilterConditions(filterConditionRows: ArrayList) { - println("list of querys saving: ${filterConditionRows.map { it.id }}") - println("list of querys previous: ${this.filterConditions.map { it.queryCondition.id }}") - filterConditionRows + Timber.d("list of querys saving: ${filterConditionRows.map { it.id }}") + Timber.d("list of querys previous: ${this.filterConditions.map { it.queryCondition.id }}") + filterConditionRows .map { it.groupId } .distinct() - .forEach { groupId-> + .forEach { groupId -> filterConditionRows .filter { it.groupId == groupId } .apply { - println("list of querys: ${this.map { it.id }}") - val casted = arrayListOf() - casted.addAll(this) - val newFilterCondition = FilterCondition(casted) - val previousCondition = filterConditions.filter { - it.filterName == newFilterCondition.filterName && it.operator == newFilterCondition.operator - } - filterConditions.removeAll(previousCondition) - filterConditions.add(newFilterCondition) - } + Timber.d("list of querys: ${this.map { it.id }}") + val casted = arrayListOf() + casted.addAll(this) + val newFilterCondition = FilterCondition(casted) + val previousCondition = filterConditions.filter { + it.filterName == newFilterCondition.filterName && it.operator == newFilterCondition.operator + } + filterConditions.removeAll(previousCondition) + filterConditions.add(newFilterCondition) + } } } - fun remove(filterCategoryRow: FilterCategoryRow) { - val sections = filterCategoryRow.filterSectionRows.map { it.name } - val savedSections = filterConditions.filter { sections.contains(it.sectionName) } - this.filterConditions.removeAll(savedSections) - } + fun remove(filterCategoryRow: FilterCategoryRow) { + val sections = filterCategoryRow.filterSectionRows.map { it.name } + val savedSections = filterConditions.filter { sections.contains(it.sectionName) } + this.filterConditions.removeAll(savedSections) + } fun countBy(filterCategoryRow: FilterCategoryRow): Int { val sections = filterCategoryRow.filterSectionRows.map { it.name } - println("list of sections $sections") - val savedSections = filterConditions.filter { sections.contains(it.sectionName) }.flatMap { it.queryCondition.id } - println("list of savedSections $savedSections") - return savedSections.size + Timber.d("list of sections $sections") + val savedSections = filterConditions.filter { sections.contains(it.sectionName) }.flatMap { it.queryCondition.id } + Timber.d("list of savedSections $savedSections") + return savedSections.size } fun contains(filterElementRow: QueryCondition): Boolean { - println("list of saved queries ${filterConditions.map { it.queryCondition.id }}") - println("list of contains ${filterElementRow.id}") - val contained = filterConditions.flatMap{ it.queryCondition.id }.contains(filterElementRow.id.first()) - println("list of : $contained") - return contained + Timber.d("list of saved queries ${filterConditions.map { it.queryCondition.id }}") + Timber.d("list of contains ${filterElementRow.id}") + val contained = filterConditions.flatMap { it.queryCondition.id }.contains(filterElementRow.id.first()) + Timber.d("list of : $contained") + return contained } /** * Get the saved value for the given [filterElementRow] */ - fun loadValueForElement(filterElementRow: QueryCondition) { + fun loadValueForElement(filterElementRow: QueryCondition) { val filtered = filterConditions.filter { it.queryCondition.id == filterElementRow.id } if (filtered.isNotEmpty()) { - return filterElementRow.updateValueBy(filtered.first()) + return filterElementRow.updateValueBy(filtered.first()) } } inline fun results(firstField: String? = null, secondField: String? = null): RealmResults { - val realmQuery = realm.where() + val realmQuery = realm.where() - if (firstField != null && secondField != null) { - return this.query.queryWith(realmQuery).distinct(firstField, secondField).findAll() - } + if (firstField != null && secondField != null) { + return this.query.queryWith(realmQuery).distinct(firstField, secondField).findAll() + } - if (firstField != null) { - return this.query.queryWith(realmQuery).distinct(firstField).findAll() - } + if (firstField != null) { + return this.query.queryWith(realmQuery).distinct(firstField).findAll() + } - return this.query.queryWith(realmQuery).findAll() - } + return this.query.queryWith(realmQuery).findAll() + } - val query: Query - get() { - val query = Query() - this.filterConditions.forEach { - query.add(it.queryCondition) - } - return query - } + val query: Query + get() { + val query = Query() + this.filterConditions.forEach { + query.add(it.queryCondition) + } + return query + } - override fun getDisplayName(context: Context): String { - if (name.isNotEmpty()) return name - return this.query.getName(context) - } + override fun getDisplayName(context: Context): String { + if (name.isNotEmpty()) return name + return this.query.getName(context) + } - override fun isValidForDelete(realm: Realm): Boolean { + override fun isValidForDelete(realm: Realm): Boolean { return true } override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int { return R.string.relationship_error } + + override val bottomSheetType: BottomSheetType + get() { + return BottomSheetType.EDIT_TEXT + } + + override fun localizedTitle(context: Context): String { + return context.getString(R.string.name) + } + + override fun editingDescriptors(map: Map): ArrayList? { + val defaultValue: String? by map + return arrayListOf(RowRepresentableEditDescriptor(defaultValue, R.string.name)) + } + + override fun updateValue(value: Any?, row: RowRepresentable) { + realm.executeTransaction { + val newName = value as String? ?: "" + if (newName.isNotEmpty()) { + name = newName + } + } + } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/FiltersListActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/FiltersListActivity.kt new file mode 100644 index 00000000..2dc2b16d --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/FiltersListActivity.kt @@ -0,0 +1,58 @@ +package net.pokeranalytics.android.ui.activity + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.fragment.app.Fragment +import kotlinx.android.synthetic.main.activity_filters_list.* +import net.pokeranalytics.android.R +import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity +import net.pokeranalytics.android.ui.fragment.FiltersListFragment +import net.pokeranalytics.android.ui.interfaces.FilterActivityRequestCode + +class FiltersListActivity : PokerAnalyticsActivity() { + + enum class IntentKey(val keyName: String) { + DATA_TYPE("DATA_TYPE"), + LIVE_DATA_TYPE("LIVE_DATA_TYPE"), + ITEM_DELETED("ITEM_DELETED"), + SHOW_ADD_BUTTON("SHOW_ADD_BUTTON"), + } + + companion object { + fun newInstance(context: Context, dataType: Int) { + context.startActivity(getIntent(context, dataType)) + } + + fun newSelectInstance(fragment: Fragment, dataType: Int, showAddButton: Boolean = true) { + val context = fragment.requireContext() + fragment.startActivityForResult(getIntent(context, dataType, showAddButton), FilterActivityRequestCode.SELECT_FILTER.ordinal) + } + + private fun getIntent(context: Context, dataType: Int, showAddButton: Boolean = true): Intent { + val intent = Intent(context, FiltersListActivity::class.java) + intent.putExtra(IntentKey.DATA_TYPE.keyName, dataType) + intent.putExtra(IntentKey.SHOW_ADD_BUTTON.keyName, showAddButton) + return intent + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_filters_list) + + initUI() + } + + /** + * Init UI + */ + private fun initUI() { + val dataType = intent.getIntExtra(IntentKey.DATA_TYPE.keyName, 0) + val showAddButton = intent.getBooleanExtra(IntentKey.SHOW_ADD_BUTTON.keyName, true) + val fragment = filtersListFragment as FiltersListFragment + fragment.setData(dataType) + fragment.updateUI(showAddButton) + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt index 68ee1388..67186d9d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt @@ -11,7 +11,6 @@ import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import io.realm.Realm import io.realm.RealmResults -import io.realm.kotlin.isValid import kotlinx.android.synthetic.main.fragment_data_list.* import net.pokeranalytics.android.R import net.pokeranalytics.android.model.LiveData @@ -25,7 +24,6 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.fragment.components.DeletableItemFragment import net.pokeranalytics.android.ui.helpers.SwipeToDeleteCallback -import net.pokeranalytics.android.ui.interfaces.FilterableType import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.util.extensions.sorted @@ -45,7 +43,7 @@ open class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataS /** * Set fragment data */ - fun setData(dataType: Int) { + open fun setData(dataType: Int) { this.dataType = LiveData.values()[dataType] this.identifiableClass = this.dataType.relatedEntity diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt index eb36582f..3aeebf19 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt @@ -14,9 +14,9 @@ import kotlinx.android.synthetic.main.fragment_filters.view.toolbar import net.pokeranalytics.android.R import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.realm.Filter -import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.FilterDetailsActivity import net.pokeranalytics.android.ui.activity.FiltersActivity +import net.pokeranalytics.android.ui.activity.FiltersListActivity import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource @@ -159,7 +159,7 @@ open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource, moreFilters.setOnClickListener { LiveData.FILTER.subType = filterableType.uniqueIdentifier - DataListActivity.newSelectInstance(this, LiveData.FILTER.ordinal, false) + FiltersListActivity.newSelectInstance(this, LiveData.FILTER.ordinal, false) } mostUsedFiltersLayout.isVisible = showMostUsedFiltersLayout diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersListFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersListFragment.kt new file mode 100644 index 00000000..8c4abc81 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersListFragment.kt @@ -0,0 +1,122 @@ +package net.pokeranalytics.android.ui.fragment + +import android.app.Activity +import android.content.Context +import android.content.Intent +import io.realm.RealmResults +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.activity.EditableDataActivity +import net.pokeranalytics.android.ui.activity.FiltersActivity +import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment +import net.pokeranalytics.android.ui.interfaces.FilterHandler.Companion.INTENT_FILTER_UPDATE_FILTER_UI +import net.pokeranalytics.android.ui.view.RowRepresentable +import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor +import net.pokeranalytics.android.ui.view.RowViewType +import net.pokeranalytics.android.util.Preferences +import timber.log.Timber + + +open class FiltersListFragment : DataListFragment() { + + private var identifiableClass: Class = Filter::class.java + private var dataType: LiveData = LiveData.FILTER + private lateinit var items: RealmResults + + /** + * Set fragment data + */ + override fun setData(dataType: Int) { + super.setData(dataType) + + this.dataType = LiveData.FILTER + this.identifiableClass = Filter::class.java + setToolbarTitle(this.dataType.pluralLocalizedTitle(requireContext())) + this.items = this.retrieveItems(getRealm()) as RealmResults + } + + override fun rowRepresentableForPosition(position: Int): RowRepresentable? { + Timber.d("rowRepresentableForPosition: ${this.items[position] as RowRepresentable}") + return this.items[position] as RowRepresentable + } + + override fun numberOfRows(): Int { + return this.items.size + } + + override fun adapterRows(): List? { + return items + } + + override fun viewTypeForPosition(position: Int): Int { + val viewType = (this.items[position] as RowRepresentable).viewType + return if (viewType != -1) viewType else RowViewType.DATA.ordinal + } + + override fun editDescriptors(row: RowRepresentable): ArrayList? { + return when (row) { + is Filter -> row.editingDescriptors(mapOf("defaultValue" to row.name)) + else -> super.editDescriptors(row) + } + } + + override fun onRowValueChanged(value: Any?, row: RowRepresentable) { + when (row) { + is Filter -> { + row.updateValue(value, row) + dataListAdapter.refreshRow(row) + updateFilterUIIfNecessary(requireContext(), row.id) + } + else -> super.onRowValueChanged(value, row) + } + } + + override fun onRowDeleted(row: RowRepresentable) { + when (row) { + is Filter -> { + val filterId = row.id + deleteItem(dataListAdapter, items, filterId) + if (filterId == Preferences.getActiveFilterId(requireContext())) { + Preferences.setActiveFilterId("", requireContext()) + updateFilterUIIfNecessary(requireContext(), "") + } + } + else -> super.onRowDeleted(row) + } + } + + override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { + when (row) { + is Filter -> { + if (fromAction) { + val data = row.editingDescriptors(mapOf("defaultValue" to row.name)) + BottomSheetFragment.create(fragmentManager, row, this, data, false, isDeletable = true, valueHasPlaceholder = false) + } else { + val intent = Intent() + intent.putExtra(FiltersActivity.IntentKey.FILTER_ID.keyName, row.id) + activity?.setResult(Activity.RESULT_OK, intent) + activity?.finish() + } + } + else -> { + val identifier = (row as Identifiable).id + EditableDataActivity.newInstanceForResult(this, this.dataType, identifier, REQUEST_CODE_DETAILS) + } + } + } + + /** + * Update filter UI + */ + fun updateFilterUIIfNecessary(context: Context, filterId: String) { + if (filterId == Preferences.getActiveFilterId(context)) { + // Send broadcast + val intent = Intent() + intent.action = INTENT_FILTER_UPDATE_FILTER_UI + context.sendBroadcast(intent) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt index 74c8d6b8..320197f1 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt @@ -42,7 +42,6 @@ class BottomSheetDoubleEditTextFragment : BottomSheetFragment() { * Init data */ private fun initData() { - valueHasPlaceholder = true isEditingBlinds = row == SessionRow.BLINDS } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetEditTextFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetEditTextFragment.kt index 537da59b..86a9a0c1 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetEditTextFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetEditTextFragment.kt @@ -43,7 +43,6 @@ class BottomSheetEditTextFragment : BottomSheetFragment() { * Init data */ private fun initData() { - valueHasPlaceholder = true } /** diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt index 8c33bf13..8657df58 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt @@ -48,7 +48,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() { isClearable: Boolean? = true, currentCurrency: Currency? = null, isDeletable: Boolean? = false, - valueHasPlaceholder: Boolean? = false + valueHasPlaceholder: Boolean? = null ): BottomSheetFragment { val bottomSheetFragment = row.bottomSheetType.newInstance() bottomSheetFragment.show(fragmentManager, "bottomSheet") diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt index a5213f7b..90f4d45c 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt @@ -36,7 +36,6 @@ class BottomSheetNumericTextFragment : BottomSheetFragment() { * Init data */ private fun initData() { - valueHasPlaceholder = true } /** diff --git a/app/src/main/java/net/pokeranalytics/android/ui/interfaces/FilterHandler.kt b/app/src/main/java/net/pokeranalytics/android/ui/interfaces/FilterHandler.kt index 64f687ba..15d45a77 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/interfaces/FilterHandler.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/interfaces/FilterHandler.kt @@ -12,69 +12,69 @@ import net.pokeranalytics.android.util.enumerations.IntIdentifiable import net.pokeranalytics.android.util.enumerations.IntSearchable enum class FilterActivityRequestCode { - SELECT_FILTER, - CREATE_FILTER, - ; + SELECT_FILTER, + CREATE_FILTER, + ; } -enum class FilterableType(override var uniqueIdentifier: Int): IntIdentifiable { - ALL(0), - SESSION(1), - TRANSACTION(2), - BANKROLL(3), - HAND_HISTORY(4), - ; +enum class FilterableType(override var uniqueIdentifier: Int) : IntIdentifiable { + ALL(0), + SESSION(1), + TRANSACTION(2), + BANKROLL(3), + HAND_HISTORY(4), + ; - companion object : IntSearchable { + companion object : IntSearchable { - override fun valuesInternal(): Array { - return values() - } - } + override fun valuesInternal(): Array { + return values() + } + } } interface FilterHandler { - companion object { - const val INTENT_FILTER_UPDATE_FILTER_UI = "net.pokeranalytics.android.UPDATE_FILTER_UI" - } - - fun applyFilter() - fun removeFilter() - - fun saveFilter(context: Context, filterId:String) { - Preferences.setActiveFilterId(filterId, context) - - - val realm = Realm.getDefaultInstance() - realm.beginTransaction() - currentFilter(context, realm)?.let { - it.useCount++ - } - realm.commitTransaction() - realm.close() - - // Send broadcast - val intent = Intent() - intent.action = INTENT_FILTER_UPDATE_FILTER_UI - context.sendBroadcast(intent) - } - - fun currentFilter(context: Context, realm: Realm): Filter? { - return Preferences.getActiveFilterId(context)?.let { - realm.where().equalTo("id", it).findFirst() - } ?: run { - null - } - } - - var currentFilterable: FilterableType - - - /** - * Manage filters - */ - fun manageFilters(fragment: Fragment) { - FiltersActivity.newInstanceForResult(fragment = fragment, currentFilterable = currentFilterable) - } + companion object { + const val INTENT_FILTER_UPDATE_FILTER_UI = "net.pokeranalytics.android.UPDATE_FILTER_UI" + } + + fun applyFilter() + fun removeFilter() + + fun saveFilter(context: Context, filterId: String) { + Preferences.setActiveFilterId(filterId, context) + + + val realm = Realm.getDefaultInstance() + realm.beginTransaction() + currentFilter(context, realm)?.let { + it.useCount++ + } + realm.commitTransaction() + realm.close() + + // Send broadcast + val intent = Intent() + intent.action = INTENT_FILTER_UPDATE_FILTER_UI + context.sendBroadcast(intent) + } + + fun currentFilter(context: Context, realm: Realm): Filter? { + return Preferences.getActiveFilterId(context)?.let { + realm.where().equalTo("id", it).findFirst() + } ?: run { + null + } + } + + var currentFilterable: FilterableType + + + /** + * Manage filters + */ + fun manageFilters(fragment: Fragment) { + FiltersActivity.newInstanceForResult(fragment = fragment, currentFilterable = currentFilterable) + } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_filters_list.xml b/app/src/main/res/layout/activity_filters_list.xml new file mode 100644 index 00000000..8560f7e1 --- /dev/null +++ b/app/src/main/res/layout/activity_filters_list.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file From 123119866a0c1ede284488def8edac866df9cf4d Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 6 Jun 2019 12:50:36 +0200 Subject: [PATCH 069/197] Fixes Oreo crash when tapping on the Feed plus button --- app/src/main/AndroidManifest.xml | 10 +++++----- .../android/ui/activity/NewDataMenuActivity.kt | 7 +++++++ .../ui/activity/components/PokerAnalyticsActivity.kt | 2 ++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c296be62..ab69d755 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -58,10 +58,10 @@ android:screenOrientation="portrait" android:windowSoftInputMode="adjustNothing" /> + - + Date: Thu, 6 Jun 2019 12:57:37 +0200 Subject: [PATCH 070/197] Fix crash with animation --- .../ui/activity/NewDataMenuActivity.kt | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt index ac7570b2..49b9b97b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt @@ -12,6 +12,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import net.pokeranalytics.android.R import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.extensions.px @@ -29,11 +30,13 @@ class NewDataMenuActivity : PokerAnalyticsActivity() { } } + private var choiceSelected = false + private var menuWillBeHidden = false private val fabSize = 48.px override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(net.pokeranalytics.android.R.layout.activity_new_data) + setContentView(R.layout.activity_new_data) initUI() } @@ -78,12 +81,18 @@ class NewDataMenuActivity : PokerAnalyticsActivity() { * Set the result and hide menu */ private fun finishWithResult(choice: Int) { + + if (choiceSelected) { + return + } + choiceSelected = true + val intent = Intent() intent.putExtra(IntentKey.CHOICE.keyName, choice) setResult(RESULT_OK, intent) GlobalScope.launch(Dispatchers.Main) { delay(200) - hideMenu(true) + hideMenu() } } @@ -105,7 +114,12 @@ class NewDataMenuActivity : PokerAnalyticsActivity() { /** * Hide menu */ - private fun hideMenu(hideQuickly: Boolean = false) { + private fun hideMenu() { + + if (menuWillBeHidden) { + return + } + menuWillBeHidden = true val cx = menuContainer.measuredWidth - fabSize / 2 val cy = menuContainer.measuredHeight - fabSize / 2 From d48ef78515ee6030021867b149265bb2f762007d Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 6 Jun 2019 14:16:12 +0200 Subject: [PATCH 071/197] Remove log --- .../main/java/net/pokeranalytics/android/model/filter/Query.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt index e5caffa0..986a4fba 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt @@ -76,7 +76,7 @@ class Query { } } - println("<<<<<< ${realmQuery.description}") +// println("<<<<<< ${realmQuery.description}") val queryLast = this.conditions.filter { it is QueryCondition.Last }.firstOrNull() From 97dc033d23e08c8cedad79533fa2353c27a7cc8e Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 6 Jun 2019 14:16:34 +0200 Subject: [PATCH 072/197] Put correct navigation tabs --- .../android/ui/activity/HomeActivity.kt | 5 +-- .../ui/activity/NewDataMenuActivity.kt | 2 +- app/src/main/res/menu/navigation_home.xml | 34 +++++-------------- 3 files changed, 10 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt index 59cc7c79..e9a540db 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt @@ -48,12 +48,9 @@ class HomeActivity : PokerAnalyticsActivity() { R.id.navigation_reports -> { displayFragment(3) } - R.id.navigation_settings -> { + R.id.navigation_more -> { displayFragment(4) } -// R.id.navigation_more -> { -// displayFragment(4) -// } } return@OnNavigationItemSelectedListener true } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt index 8cc3dfcb..3a85ad5f 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt @@ -40,7 +40,7 @@ class NewDataMenuActivity : PokerAnalyticsActivity() { super.onCreate(savedInstanceState) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { // used to fix Oreo crash - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; } setContentView(R.layout.activity_new_data) diff --git a/app/src/main/res/menu/navigation_home.xml b/app/src/main/res/menu/navigation_home.xml index 7d41675a..d4a0f3b6 100644 --- a/app/src/main/res/menu/navigation_home.xml +++ b/app/src/main/res/menu/navigation_home.xml @@ -1,24 +1,6 @@ - - - - - - - + + + + + From 5b7d8ab2b99106c727f8cabf881ffd4f144646c3 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 6 Jun 2019 14:39:19 +0200 Subject: [PATCH 073/197] Merge Laurent updates --- .../net/pokeranalytics/android/model/realm/Filter.kt | 9 +++++---- .../android/ui/activity/NewDataMenuActivity.kt | 7 +++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt index a65edf11..8fd1e6e9 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt @@ -48,12 +48,13 @@ open class Filter : RealmObject(), RowRepresentable, Editable, Deletable, Counta } inline fun queryOn(realm: Realm, query: Query, sortField: String? = null): RealmResults { - val realmQuery = realm.where() + val rootQuery = realm.where() + var realmQuery = query.queryWith(rootQuery) sortField?.let { - return query.queryWith(realmQuery).sort(it).findAll() - } ?: run { - return query.queryWith(realmQuery).findAll() + realmQuery = realmQuery.sort(it) } + val desc = realmQuery.description + return realmQuery.findAll() } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt index 49b9b97b..8cc3dfcb 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt @@ -4,6 +4,8 @@ import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.content.Context import android.content.Intent +import android.content.pm.ActivityInfo +import android.os.Build import android.os.Bundle import android.view.View import android.view.ViewAnimationUtils @@ -36,6 +38,11 @@ class NewDataMenuActivity : PokerAnalyticsActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { // used to fix Oreo crash + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } + setContentView(R.layout.activity_new_data) initUI() } From c1d271b495e86ec27b111ac505bdb9457b00e547 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 6 Jun 2019 17:27:15 +0200 Subject: [PATCH 074/197] Add Top 10 view --- app/src/main/AndroidManifest.xml | 5 + .../model/extensions/SessionExtensions.kt | 44 ++++- .../android/ui/activity/Top10Activity.kt | 33 ++++ .../android/ui/fragment/MoreFragment.kt | 2 + .../android/ui/fragment/Top10Fragment.kt | 154 ++++++++++++++++++ .../android/ui/view/RowViewType.kt | 47 ++++++ .../android/ui/view/SessionRowView.kt | 39 +---- .../ui/view/rowrepresentable/MoreTabRow.kt | 3 + app/src/main/res/drawable/ic_outline_star.xml | 5 + app/src/main/res/layout/activity_top_10.xml | 15 ++ app/src/main/res/layout/fragment_top_10.xml | 71 ++++++++ app/src/main/res/layout/row_top_10.xml | 71 ++++++++ app/src/main/res/values/styles.xml | 16 ++ 13 files changed, 467 insertions(+), 38 deletions(-) create mode 100644 app/src/main/java/net/pokeranalytics/android/ui/activity/Top10Activity.kt create mode 100644 app/src/main/java/net/pokeranalytics/android/ui/fragment/Top10Fragment.kt create mode 100644 app/src/main/res/drawable/ic_outline_star.xml create mode 100644 app/src/main/res/layout/activity_top_10.xml create mode 100644 app/src/main/res/layout/fragment_top_10.xml create mode 100644 app/src/main/res/layout/row_top_10.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8cf3f769..04c3d2ef 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -74,6 +74,11 @@ android:launchMode="singleTop" android:screenOrientation="portrait" /> + + () + if (isTournament()) { + + tournamentEntryFee?.let { + parameters.add(it.toCurrency(currency)) + } + + tournamentName?.let { + parameters.add(it.name) + } ?: run { + parameters.add(getFormattedGame()) + tournamentType?.let { type -> + parameters.add(TournamentType.values()[type].localizedTitle(context)) + } + } + if (parameters.size == 0) { + parameters.add(context.getString(R.string.tournament).capitalize()) + } + } else { + if (cgSmallBlind != null && cgBigBlind != null) { + parameters.add(getFormattedBlinds()) + } + game?.let { + parameters.add(getFormattedGame()) + } + + if (parameters.size == 0) { + parameters.add(context.getString(R.string.cash_game).capitalize()) + } + } + return parameters.joinToString(separator = " ") } val AbstractList.hourlyDuration: Double @@ -95,4 +137,4 @@ fun MutableList.update(timeInterval: TimeInterval): MutableList BankrollActivity.newInstance(requireContext()) + MoreTabRow.TOP_10 -> Top10Activity.newInstance(requireContext()) MoreTabRow.SETTINGS -> SettingsActivity.newInstance(requireContext()) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/Top10Fragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/Top10Fragment.kt new file mode 100644 index 00000000..9dfc8361 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/Top10Fragment.kt @@ -0,0 +1,154 @@ +package net.pokeranalytics.android.ui.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.google.android.material.tabs.TabLayout +import io.realm.RealmModel +import io.realm.RealmResults +import io.realm.Sort +import io.realm.kotlin.where +import kotlinx.android.synthetic.main.fragment_feed.* +import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.realm.Session +import net.pokeranalytics.android.model.realm.Transaction +import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter +import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource +import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate +import net.pokeranalytics.android.ui.fragment.components.RealmFragment +import net.pokeranalytics.android.ui.view.RowRepresentable +import net.pokeranalytics.android.ui.view.RowViewType +import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager + + +class Top10Fragment : RealmFragment(), RowRepresentableDataSource, RowRepresentableDelegate { + + private enum class Tab { + CASH_GAMES, + TOURNAMENTS + } + + companion object { + fun newInstance(): Top10Fragment { + val fragment = Top10Fragment() + val bundle = Bundle() + fragment.arguments = bundle + return fragment + } + } + + private lateinit var dataListAdapter: RowRepresentableAdapter + private lateinit var realmCashGames: RealmResults + private lateinit var realmTournaments: RealmResults + + private var currentTab: Tab = Tab.CASH_GAMES + + override val observedEntities: List> = listOf(Session::class.java, Transaction::class.java) + + override fun entitiesChanged(clazz: Class) { + super.entitiesChanged(clazz) + when (clazz.kotlin) { + Session::class -> { + this.dataListAdapter.notifyDataSetChanged() + } + } + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + super.onCreateView(inflater, container, savedInstanceState) + return inflater.inflate(R.layout.fragment_top_10, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initUI() + initData() + } + + override fun adapterRows(): List? { + return when (currentTab) { + Tab.CASH_GAMES -> realmCashGames + Tab.TOURNAMENTS -> realmTournaments + } + } + + override fun rowRepresentableForPosition(position: Int): RowRepresentable? { + return when (currentTab) { + Tab.CASH_GAMES -> realmCashGames[position] + Tab.TOURNAMENTS -> realmTournaments[position] + } + } + + override fun numberOfRows(): Int { + return when (currentTab) { + Tab.CASH_GAMES -> realmCashGames.size + Tab.TOURNAMENTS -> realmTournaments.size + } + } + + override fun viewTypeForPosition(position: Int): Int { + return RowViewType.ROW_TOP_10.ordinal + } + + /** + * Init UI + */ + private fun initUI() { + + setDisplayHomeAsUpEnabled(true) + + tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { + override fun onTabSelected(tab: TabLayout.Tab) { + when (tab.position) { + 0 -> { + currentTab = Tab.CASH_GAMES + dataListAdapter.notifyDataSetChanged() + } + 1 -> { + currentTab = Tab.TOURNAMENTS + } + } + dataListAdapter.notifyDataSetChanged() + } + + override fun onTabUnselected(tab: TabLayout.Tab) { + } + + override fun onTabReselected(tab: TabLayout.Tab) { + } + }) + + + val viewManager = SmoothScrollLinearLayoutManager(requireContext()) + recyclerView.apply { + setHasFixedSize(true) + layoutManager = viewManager + } + + } + + /** + * Init data + */ + private fun initData() { + + this.realmCashGames = getRealm().where() + .equalTo("type", Session.Type.CASH_GAME.ordinal) + .greaterThanOrEqualTo("result.net", 0.0) + .sort("result.net", Sort.DESCENDING) + .limit(10) + .findAll() + + this.realmTournaments = getRealm().where() + .equalTo("type", Session.Type.TOURNAMENT.ordinal) + .greaterThanOrEqualTo("result.net", 0.0) + .sort("result.net", Sort.DESCENDING) + .limit(10) + .findAll() + + dataListAdapter = RowRepresentableAdapter(this, this) + recyclerView.adapter = dataListAdapter + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt index 12ccaece..3ad02065 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt @@ -26,6 +26,7 @@ import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.ComputedStat import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.bankroll.BankrollReport +import net.pokeranalytics.android.model.extensions.getFormattedGameType import net.pokeranalytics.android.model.realm.CustomField import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Transaction @@ -37,6 +38,7 @@ import net.pokeranalytics.android.ui.extensions.setTextFormat import net.pokeranalytics.android.ui.graph.AxisFormatting import net.pokeranalytics.android.ui.graph.setStyle import net.pokeranalytics.android.ui.view.rowrepresentable.* +import net.pokeranalytics.android.util.extensions.longDate /** * An interface used to factor the configuration of RecyclerView.ViewHolder @@ -78,6 +80,7 @@ enum class RowViewType(private var layoutRes: Int) { // Custom row ROW_SESSION(R.layout.row_feed_session), ROW_TRANSACTION(R.layout.row_transaction), + ROW_TOP_10(R.layout.row_top_10), ROW_BUTTON(R.layout.row_button), ROW_FOLLOW_US(R.layout.row_follow_us), STATS(R.layout.row_stats_title_value), @@ -110,6 +113,10 @@ enum class RowViewType(private var layoutRes: Int) { // Row Transaction ROW_TRANSACTION -> RowTransactionViewHolder(layout) + // Row Transaction + ROW_TOP_10 -> RowTop10ViewHolder(layout) + + // Row Button ROW_BUTTON -> RowButtonViewHolder(layout) @@ -513,6 +520,46 @@ enum class RowViewType(private var layoutRes: Int) { } } + + /** + * Display a top 10 row + */ + inner class RowTop10ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { + override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) { + + if (row is Session) { + + itemView.findViewById(R.id.gameResult)?.let { gameResult -> + val result = row.result?.net ?: 0.0 + val formattedStat = ComputedStat(Stat.NET_RESULT, result, currency = row.currency).format() + gameResult.setTextFormat(formattedStat, itemView.context) + } + + itemView.findViewById(R.id.top10ResultPart1)?.let { part1 -> + part1.text = row.getFormattedGameType(itemView.context) + } + + itemView.findViewById(R.id.top10ResultPart2)?.let { part2 -> + var content = row.getFormattedDuration() + + if (!row.location?.name.isNullOrEmpty()) { + content += " - " + row.location?.name + } else if (!row.bankroll?.name.isNullOrEmpty()) { + content += " - " + row.bankroll?.name + } + + part2.text = content + } + + itemView.findViewById(R.id.top10ResultPart3)?.let { part3 -> + part3.text = row.creationDate.longDate() + } + } + + } + } + + /** * Display a separator */ diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt index 40db96da..69edd181 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt @@ -11,15 +11,14 @@ import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.ComputedStat import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.model.TableSize -import net.pokeranalytics.android.model.TournamentType import net.pokeranalytics.android.model.extensions.SessionState +import net.pokeranalytics.android.model.extensions.getFormattedGameType import net.pokeranalytics.android.model.extensions.getState import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.ui.extensions.setTextFormat import net.pokeranalytics.android.util.extensions.getDayNumber import net.pokeranalytics.android.util.extensions.getShortDayName import net.pokeranalytics.android.util.extensions.shortTime -import net.pokeranalytics.android.util.extensions.toCurrency /** * Display a row session @@ -65,41 +64,7 @@ class SessionRowView : FrameLayout { rowSession.dateNumber.text = date.getDayNumber() // Title / Game type - - var parameters = mutableListOf() - if (session.isTournament()) { - - session.tournamentEntryFee?.let { - parameters.add(it.toCurrency(session.currency)) - } - - session.tournamentName?.let { - parameters.add(it.name) - } ?: run { - parameters.add(session.getFormattedGame()) - session.tournamentType?.let { type -> - parameters.add(TournamentType.values()[type].localizedTitle(context)) - } - } - - if (parameters.size == 0) { - parameters.add(context.getString(R.string.tournament).capitalize()) - } - } else { - if (session.cgSmallBlind != null && session.cgBigBlind != null) { - parameters.add(session.getFormattedBlinds()) - } - session.game?.let { - parameters.add(session.getFormattedGame()) - } - - if (parameters.size == 0) { - parameters.add(context.getString(R.string.cash_game).capitalize()) - } - } - val title = parameters.joinToString(separator = " ") - - rowSession.sessionTitle.text = title + rowSession.sessionTitle.text = session.getFormattedGameType(context) // Duration rowSession.sessionInfoDurationValue.text = session.getFormattedDuration() diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/MoreTabRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/MoreTabRow.kt index 4e2fe8bc..3885a4a1 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/MoreTabRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/MoreTabRow.kt @@ -9,12 +9,14 @@ import net.pokeranalytics.android.ui.view.RowViewType */ enum class MoreTabRow : RowRepresentable { BANKROLL, + TOP_10, SETTINGS; override val resId: Int? get() { return when(this) { BANKROLL -> R.string.bankroll + TOP_10 -> R.string.top_10 SETTINGS -> R.string.services } } @@ -23,6 +25,7 @@ enum class MoreTabRow : RowRepresentable { get() { return when(this) { BANKROLL -> R.drawable.ic_outline_lock + TOP_10 -> R.drawable.ic_outline_star SETTINGS -> R.drawable.ic_outline_settings } } diff --git a/app/src/main/res/drawable/ic_outline_star.xml b/app/src/main/res/drawable/ic_outline_star.xml new file mode 100644 index 00000000..3fc251d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_star.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/activity_top_10.xml b/app/src/main/res/layout/activity_top_10.xml new file mode 100644 index 00000000..44318e12 --- /dev/null +++ b/app/src/main/res/layout/activity_top_10.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_top_10.xml b/app/src/main/res/layout/fragment_top_10.xml new file mode 100644 index 00000000..07d841a5 --- /dev/null +++ b/app/src/main/res/layout/fragment_top_10.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/row_top_10.xml b/app/src/main/res/layout/row_top_10.xml new file mode 100644 index 00000000..6d143692 --- /dev/null +++ b/app/src/main/res/layout/row_top_10.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index eecdebee..43efcfbc 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -228,6 +228,22 @@ @color/green + + + + + + From d1136c317afa30a57267973c63bab38154bb1ea8 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 6 Jun 2019 18:10:46 +0200 Subject: [PATCH 075/197] Update Top 10 UI --- .../android/ui/view/RowViewType.kt | 29 ++++--- app/src/main/res/layout/row_top_10.xml | 80 +++++++++++++++++-- 2 files changed, 94 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt index 3ad02065..244e8674 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt @@ -539,18 +539,27 @@ enum class RowViewType(private var layoutRes: Int) { part1.text = row.getFormattedGameType(itemView.context) } - itemView.findViewById(R.id.top10ResultPart2)?.let { part2 -> - var content = row.getFormattedDuration() - - if (!row.location?.name.isNullOrEmpty()) { - content += " - " + row.location?.name - } else if (!row.bankroll?.name.isNullOrEmpty()) { - content += " - " + row.bankroll?.name - } - - part2.text = content + // Duration + val durationIcon = itemView.findViewById(R.id.sessionInfoDurationIcon) + val durationText = itemView.findViewById(R.id.sessionInfoDuration) + durationIcon?.isVisible = true + durationText?.isVisible = true + durationText?.text = row.getFormattedDuration() + + // Location + val locationIcon = itemView.findViewById(R.id.sessionInfoLocationIcon) + val locationText = itemView.findViewById(R.id.sessionInfoLocation) + + if (!row.location?.name.isNullOrEmpty()) { + locationIcon?.isVisible = true + locationText?.isVisible = true + locationText?.text = row.location?.name + } else { + locationIcon?.isVisible = false + locationText?.isVisible = false } + itemView.findViewById(R.id.top10ResultPart3)?.let { part3 -> part3.text = row.creationDate.longDate() } diff --git a/app/src/main/res/layout/row_top_10.xml b/app/src/main/res/layout/row_top_10.xml index 6d143692..157d62a2 100644 --- a/app/src/main/res/layout/row_top_10.xml +++ b/app/src/main/res/layout/row_top_10.xml @@ -13,8 +13,8 @@ android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginTop="8dp" - android:gravity="center" android:layout_marginEnd="16dp" + android:gravity="center" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" @@ -25,17 +25,87 @@ style="@style/PokerAnalyticsTheme.TextView.Top10Row" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="16dp" + android:layout_marginStart="8dp" android:layout_marginTop="4dp" - android:layout_marginEnd="16dp" + android:layout_marginEnd="8dp" android:gravity="center" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/gameResult" app:layout_constraintVertical_chainStyle="packed" tools:text="$300 NL Hold'em" /> + + + + + + + + + + + Date: Thu, 6 Jun 2019 19:00:39 +0200 Subject: [PATCH 076/197] Bump version code --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 4304c29c..b46f503c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,7 +29,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 30 + versionCode 31 versionName "2.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From f5babae7344be97acfe3bb5d260e6ff8684d46e0 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 7 Jun 2019 14:23:10 +0200 Subject: [PATCH 077/197] Upgrade test libs + bump version --- app/build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b46f503c..1c421f35 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,7 +29,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 31 + versionCode 32 versionName "2.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -114,10 +114,10 @@ dependencies { implementation 'org.apache.commons:commons-csv:1.6' // Instrumented Tests - androidTestImplementation 'androidx.test:core:1.1.0' - androidTestImplementation 'androidx.test:runner:1.1.1' - androidTestImplementation 'androidx.test:rules:1.1.1' - androidTestImplementation 'androidx.test.ext:junit:1.1.0' + androidTestImplementation 'androidx.test:core:1.2.0' + androidTestImplementation 'androidx.test:runner:1.2.0' + androidTestImplementation 'androidx.test:rules:1.2.0' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' // Test testImplementation 'junit:junit:4.12' From db056d42f976ffbfc5de25151b846b6a4a469fdd Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 7 Jun 2019 14:38:32 +0200 Subject: [PATCH 078/197] Hides subscription row --- .../android/ui/view/rowrepresentable/SettingRow.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt index e3ab95ea..adda5f89 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt @@ -46,7 +46,8 @@ enum class SettingRow : RowRepresentable { val rows = ArrayList() rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.information)) - rows.addAll(arrayListOf(SUBSCRIPTION, VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) + rows.addAll(arrayListOf(VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) +// rows.addAll(arrayListOf(SUBSCRIPTION, VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.follow_us)) rows.addAll(arrayListOf(FOLLOW_US)) From 9ed96f17a09e0297c57565060a9c17d398b24371 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 7 Jun 2019 14:49:37 +0200 Subject: [PATCH 079/197] french translations --- app/src/main/res/values-fr/strings.xml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 28d11de2..67ab23ec 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -15,7 +15,28 @@ Passer Pro d\'essai gratuit Cette bankroll contient au moins une transaction empêchant la suppression. - + Illimité + Suivez toute votre vie de joueur en ajoutant autant de données que vous le souhaitez + Hors ligne avant tout + Poker Analytics est disponible à tout moment et vos données vous appartiennent. Vous êtes pour l\'instant en charge de faire des sauvegarde mais cela changera dans le futur! + Vie privée + Nous ne sauvegardons pas vos données, nous ne savons rien de vos gains ni de vos pertes + Support + Nous essayons de répondre le plus vite possible, en français ou en anglais ! + Chargement, veuillez patienter… + Choisissez un type de rapport + Choisissez une statistique, ou plusieurs + Sélectionnez un critère de comparaison, ou plusieurs + Sélectionnez un filtre ou lancez maintenant le rapport + Afficher le rapport + Evolution + Sauvegarder le rapport + Voulez-vous effectuer l\'import des données? + Graphique de comparaison + Le filtre ne peut être effacé car utilisé en ce moment + Champ perso + L\'élement est utilisé dans une ou plusieurs transactions…Veuillez effacer les transactions en premier lieu + À partir de Jusqu\'à ère From 95e4755cdf44f7eaa14b402552d99b7557064025 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 7 Jun 2019 14:50:32 +0200 Subject: [PATCH 080/197] cleanup --- app/src/main/res/values-fr/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 67ab23ec..f382b4fe 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -36,7 +36,7 @@ Le filtre ne peut être effacé car utilisé en ce moment Champ perso L\'élement est utilisé dans une ou plusieurs transactions…Veuillez effacer les transactions en premier lieu - + À partir de Jusqu\'à ère From f0dfe12ed9c41250fa551b8fde19178df0c15223 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 7 Jun 2019 18:03:05 +0200 Subject: [PATCH 081/197] bumped version 33 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 1c421f35..77cc85ce 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,7 +29,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 32 + versionCode 33 versionName "2.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From 6b452bd17e86d55da856f04ce1d1ec7ba559ee27 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Mon, 10 Jun 2019 10:45:49 +0200 Subject: [PATCH 082/197] realm: change to executeTransaction (from beginTransaction / commitTransaction) --- .../android/ui/fragment/FeedFragment.kt | 7 +++-- .../ui/fragment/FilterDetailsFragment.kt | 10 +++---- .../android/ui/fragment/FiltersFragment.kt | 26 +++++++++---------- .../android/ui/fragment/SessionFragment.kt | 19 +++++++------- .../android/ui/interfaces/FilterHandler.kt | 12 ++++----- 5 files changed, 34 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt index 35454cc4..3d026bfa 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt @@ -308,10 +308,9 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { * Delete selected transaction */ private fun deleteSelectedTransaction() { - val realm = getRealm() - realm.beginTransaction() - selectedTransaction?.deleteFromRealm() - realm.commitTransaction() + getRealm().executeTransaction { + selectedTransaction?.deleteFromRealm() + } selectedTransactionPosition = -1 } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FilterDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FilterDetailsFragment.kt index 7fe858e8..481557e5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FilterDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FilterDetailsFragment.kt @@ -243,12 +243,10 @@ open class FilterDetailsFragment : RealmFragment(), StaticRowRepresentableDataSo Timber.d("Selected rows: $it") } - val realm = getRealm() - realm.beginTransaction() - currentFilter?.remove(filterCategoryRow) - currentFilter?.createOrUpdateFilterConditions(selectedRows) - realm.commitTransaction() - + getRealm().executeTransaction { + currentFilter?.remove(filterCategoryRow) + currentFilter?.createOrUpdateFilterConditions(selectedRows) + } currentFilter?.filterConditions?.forEach { Timber.d("Condition: $it") } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt index 3aeebf19..0a1b696e 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt @@ -251,13 +251,12 @@ open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource, * Validate the updates of the queryWith */ private fun validateUpdates() { - val realm = getRealm() - realm.beginTransaction() - currentFilter?.let { - it.name = it.query.getName(requireContext()) - realm.copyToRealmOrUpdate(it) - } - realm.commitTransaction() + getRealm().executeTransaction { realm -> + currentFilter?.let { + it.name = it.query.getName(requireContext()) + realm.copyToRealmOrUpdate(it) + } + } val filterId = currentFilter?.id ?: "" finishActivityWithResult(filterId) @@ -268,13 +267,12 @@ open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource, */ private fun cancelUpdates() { val filterId = filterCopy?.id ?: "" - val realm = getRealm() - realm.beginTransaction() - filterCopy?.let { - realm.copyToRealmOrUpdate(it) - } - realm.commitTransaction() - finishActivityWithResult(filterId) + getRealm().executeTransaction { realm -> + filterCopy?.let { + realm.copyToRealmOrUpdate(it) + } + } + finishActivityWithResult(filterId) } /** diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt index cb13262e..aefaa32d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt @@ -67,20 +67,19 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate { currentSession = sessionRealm sessionHasBeenCustomized = true } else { - realm.beginTransaction() - currentSession = Session.newInstance(realm, isTournament) - FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, null, requireContext()) - realm.commitTransaction() - + realm.executeTransaction { executeRealm -> + currentSession = Session.newInstance(executeRealm, isTournament) + FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, null, requireContext()) + } // Find the nearest location around the user parentActivity?.findNearestLocation { it?.let { location -> - realm.beginTransaction() - val realmLocation = realm.findById(location.id) - FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, realmLocation, requireContext()) + realm.executeTransaction { executeRealm -> + val realmLocation = executeRealm.findById(location.id) + FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, realmLocation, requireContext()) - currentSession.location = realmLocation - realm.commitTransaction() + currentSession.location = realmLocation + } updateSessionUI(true) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/interfaces/FilterHandler.kt b/app/src/main/java/net/pokeranalytics/android/ui/interfaces/FilterHandler.kt index 15d45a77..8e8c1167 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/interfaces/FilterHandler.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/interfaces/FilterHandler.kt @@ -47,12 +47,12 @@ interface FilterHandler { val realm = Realm.getDefaultInstance() - realm.beginTransaction() - currentFilter(context, realm)?.let { - it.useCount++ - } - realm.commitTransaction() - realm.close() + realm.executeTransaction { executeRealm -> + currentFilter(context, executeRealm)?.let { + it.useCount++ + } + } + realm.close() // Send broadcast val intent = Intent() From 2210016627e7c00a806347e5bd3ad2c34392bbed Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Mon, 10 Jun 2019 11:02:28 +0200 Subject: [PATCH 083/197] filter / duration fix crash when the user validate empty values --- .../components/bottomsheet/BottomSheetDoubleEditTextFragment.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt index 320197f1..814ff646 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt @@ -35,6 +35,8 @@ class BottomSheetDoubleEditTextFragment : BottomSheetFragment() { } override fun getValue(): Any? { + if (values.isEmpty()) { return null } + if (values.all { it.isEmpty() }) { return null } return values } From fbaf8c869e0c2a8cc60a895fc06af3a102bbd182 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Mon, 10 Jun 2019 13:00:44 +0200 Subject: [PATCH 084/197] Filter: fix issue with place holder --- .../bottomsheet/BottomSheetDoubleEditTextFragment.kt | 4 ++-- .../android/ui/view/rowrepresentable/FilterElementRow.kt | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt index 814ff646..14adf917 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt @@ -71,8 +71,8 @@ class BottomSheetDoubleEditTextFragment : BottomSheetFragment() { editText2.inputType = data[1].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES if (valueHasPlaceholder) { - editText1.hint = values[0] - editText2.hint = values[1] + if (values[0].isNotBlank()) { editText1.hint = values[0] } + if (values[1].isNotBlank()) { editText2.hint = values[1] } } else { editText1.setText(values[0]) editText2.setText(values[1]) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt index 3e8b783e..9829f9ee 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt @@ -22,8 +22,13 @@ interface FilterElementRow : RowRepresentable { } is QueryCondition.ListOfValues<*> -> { val valueAsString: String? by map + val hint = when (this.operator) { + QueryCondition.Operator.MORE, QueryCondition.Operator.LESS -> this.filterSectionRow.resId + else -> this.resId + } + arrayListOf( - RowRepresentableEditDescriptor(valueAsString, this.resId, inputType = InputType.TYPE_CLASS_NUMBER) + RowRepresentableEditDescriptor(valueAsString, hint, inputType = InputType.TYPE_CLASS_NUMBER) ) } else -> super.editingDescriptors(map) From ed372c1c712d5ddbb0fc90104accf38986321621 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 10 Jun 2019 14:02:33 +0200 Subject: [PATCH 085/197] Fixing issue where tab item were truncated on selection --- app/src/main/res/values/dimens.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 47c82246..802da918 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -1,5 +1,8 @@ - + 16dp 16dp + + 12sp + 11sp From 7cc2510da3ed7d8d6afbfb962de19f511df250a6 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 10 Jun 2019 14:15:28 +0200 Subject: [PATCH 086/197] Fixing tab item sizes --- app/src/main/res/values/dimens.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 802da918..1f75d3f0 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -1,8 +1,8 @@ - - 16dp - 16dp + +16dp +16dp - 12sp - 11sp +12sp +11sp From 3e9e61b9483812290d4716a65376f556252737f9 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Mon, 10 Jun 2019 14:15:42 +0200 Subject: [PATCH 087/197] Filter / custom field : fix res id issue for place holder --- .../android/ui/view/rowrepresentable/FilterElementRow.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt index 9829f9ee..43860b3a 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt @@ -23,7 +23,13 @@ interface FilterElementRow : RowRepresentable { is QueryCondition.ListOfValues<*> -> { val valueAsString: String? by map val hint = when (this.operator) { - QueryCondition.Operator.MORE, QueryCondition.Operator.LESS -> this.filterSectionRow.resId + QueryCondition.Operator.MORE, QueryCondition.Operator.LESS -> { + when (this) { + is QueryCondition.CustomFieldNumberQuery -> R.string.value + is QueryCondition.CustomFieldAmountQuery -> R.string.amount + else -> this.filterSectionRow.resId + } + } else -> this.resId } From 61e0d080f059dbfa75404902a874e332a6b36e55 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 10 Jun 2019 14:25:46 +0200 Subject: [PATCH 088/197] file formatting --- app/src/main/res/values/dimens.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 1f75d3f0..802da918 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -1,8 +1,8 @@ - -16dp -16dp + + 16dp + 16dp -12sp -11sp + 12sp + 11sp From 31c2038857c7378a48d06e89e7799b284f4848c7 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 10 Jun 2019 14:46:26 +0200 Subject: [PATCH 089/197] bumping to 35 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 77cc85ce..91d6b38d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,7 +29,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 33 + versionCode 35 versionName "2.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From 4c79b32c1f4ecf0f40858dab28448f2384e434e7 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 11 Jun 2019 18:07:20 +0200 Subject: [PATCH 090/197] Fixing bankroll report updates --- .../android/PokerAnalyticsApplication.kt | 2 +- .../pokeranalytics/android/calculus/Stat.kt | 1 + .../calculus/bankroll/BankrollCalculator.kt | 9 +- .../calculus/bankroll/BankrollReport.kt | 93 ++----- .../bankroll/BankrollReportManager.kt | 114 ++++++++ .../android/exceptions/Exceptions.kt | 1 + .../android/ui/activity/BankrollActivity.kt | 41 --- .../android/ui/activity/components/Codes.kt | 2 + .../ui/fragment/BankrollDetailsFragment.kt | 135 +++++++--- .../android/ui/fragment/BankrollFragment.kt | 127 ++++----- .../android/ui/fragment/FeedFragment.kt | 13 +- .../android/ui/fragment/SessionFragment.kt | 4 + .../components/DeletableItemFragment.kt | 4 +- .../ui/fragment/data/DataManagerFragment.kt | 4 + .../fragment/data/TransactionDataFragment.kt | 8 + .../android/ui/view/RowViewType.kt | 251 ++++++++++-------- .../view/rowrepresentable/BankrollMainRow.kt | 12 + .../CustomizableRowRepresentable.kt | 11 + .../ui/view/rowrepresentable/GraphRow.kt | 9 +- 19 files changed, 502 insertions(+), 339 deletions(-) create mode 100644 app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReportManager.kt create mode 100644 app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/BankrollMainRow.kt diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index 35ea4536..1b81d955 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -60,7 +60,7 @@ class PokerAnalyticsApplication : Application() { if (BuildConfig.DEBUG) { Timber.d("UserPreferences.defaultCurrency: ${UserDefaults.currency.symbol}") -// this.createFakeSessions() + this.createFakeSessions() } Patcher.patchAll(this.applicationContext) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt index d065af5f..2b8a30c8 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt @@ -177,6 +177,7 @@ enum class Stat(override var uniqueIdentifier: Int) : IntIdentifiable, RowRepres private val threshold: Double get() { return when (this) { + RISK_OF_RUIN -> 5.0 WIN_RATIO -> 50.0 else -> 0.0 } diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt index 2f889e24..3f7b144a 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt @@ -5,7 +5,9 @@ import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.ComputableGroup import net.pokeranalytics.android.calculus.ComputedResults import net.pokeranalytics.android.calculus.Stat +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.realm.* +import net.pokeranalytics.android.util.extensions.findById class BankrollCalculator { @@ -18,7 +20,10 @@ class BankrollCalculator { val report = BankrollReport(setup) val bankrolls: List = - if (setup.bankroll != null) listOf(setup.bankroll) + if (setup.bankrollId != null) { + val bankroll = realm.findById(setup.bankrollId) ?: throw PAIllegalStateException("Bankroll not found with id=${setup.bankrollId}") + listOf(bankroll) + } else realm.where(Bankroll::class.java).findAll() var initialValue = 0.0 @@ -41,7 +46,7 @@ class BankrollCalculator { report.transactionsNet = transactionNet report.initial = initialValue - val query = setup.query + val query = setup.query(realm) val transactions = Filter.queryOn(realm, query) report.addDatedItems(transactions) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt index 2b7e4724..b6c079d6 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt @@ -3,54 +3,22 @@ package net.pokeranalytics.android.calculus.bankroll import android.content.Context import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.data.LineDataSet +import io.realm.Realm import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.interfaces.DatedValue import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Transaction import net.pokeranalytics.android.ui.graph.DataSetFactory -import net.pokeranalytics.android.ui.view.RowRepresentable -import net.pokeranalytics.android.ui.view.RowViewType +import net.pokeranalytics.android.util.extensions.findById import java.util.* import kotlin.collections.HashMap -//object BankrollReportManager { -// -// var mainReport: BankrollReport? = null -// var reports: MutableMap = mutableMapOf() -// -// fun udpateBankrolls(bankrolls: List) { -// this.invalidateMainReport() -// bankrolls.forEach { -// this.reports.remove(it.id) -// } -// } -// -// fun deleteBankrolls(bankrolls: List) { -// this.invalidateMainReport() -// bankrolls.forEach { -// this.reports.remove(it.id) -// } -// } -// -// private fun invalidateMainReport() { -// this.mainReport = null -// } -// -// private fun launchReports(bankrolls: List) { -// -// this.mainReport = BankrollCalculator.computeReport() -// -// -// } -// -//} - /** * This class holds the results from the BankrollCalculator computations * It has all the information required for the Bankroll various displays */ -class BankrollReport(var setup: BankrollReportSetup) : RowRepresentable { +class BankrollReport(var setup: BankrollReportSetup) { /** * The value of the bankroll @@ -150,15 +118,6 @@ class BankrollReport(var setup: BankrollReportSetup) : RowRepresentable { */ private var evolutionItems: MutableList = mutableListOf() - override val viewType: Int - get() { - return if (setup.bankroll == null) { - RowViewType.LEGEND_DEFAULT.ordinal - } else { - RowViewType.TITLE_VALUE_ARROW.ordinal - } - } - /** * Adds a list of dated items to the evolution items used to get the bankroll graph */ @@ -176,7 +135,7 @@ class BankrollReport(var setup: BankrollReportSetup) : RowRepresentable { var bucket = this.transactionBuckets[type.id] if (bucket == null) { - val b = TransactionBucket(this.setup.virtualBankroll) + val b = TransactionBucket(type.name, this.setup.virtualBankroll) this.transactionBuckets[type.id] = b bucket = b } @@ -200,7 +159,7 @@ class BankrollReport(var setup: BankrollReportSetup) : RowRepresentable { this.evolutionItems.sortBy { it.date } - var total = 0.0 + var total = this.initial this.evolutionItems.forEach { total += it.amount val point = BRGraphPoint(total, it.date, it) @@ -228,7 +187,7 @@ class BankrollReport(var setup: BankrollReportSetup) : RowRepresentable { * A class describing the parameters required to launch a bankroll report * */ -class BankrollReportSetup(val bankroll: Bankroll? = null, val from: Date? = null, val to: Date? = null) { +class BankrollReportSetup(val bankrollId: String? = null, val from: Date? = null, val to: Date? = null) { /** * Returns whether the setup concerns the virtual bankroll, @@ -236,32 +195,32 @@ class BankrollReportSetup(val bankroll: Bankroll? = null, val from: Date? = null */ val virtualBankroll: Boolean get() { - return this.bankroll == null + return this.bankrollId == null } /** * the query used to get bankroll transactions */ - val query: Query - get() { - val query = Query() + fun query(realm: Realm): Query { + val query = Query() - this.bankroll?.let { - val bankrollCondition = QueryCondition.AnyBankroll(bankroll) - query.add(bankrollCondition) - } - this.from?.let { - val fromCondition = QueryCondition.StartedFromDate() - fromCondition.singleValue = it - query.add(fromCondition) - } - this.to?.let { - val toCondition = QueryCondition.StartedToDate() - toCondition.singleValue = it - query.add(toCondition) - } - return query + this.bankrollId?.let { + val bankroll = realm.findById(it) ?: throw IllegalStateException("Bankroll not found with id $it") + val bankrollCondition = QueryCondition.AnyBankroll(bankroll) + query.add(bankrollCondition) } + this.from?.let { + val fromCondition = QueryCondition.StartedFromDate() + fromCondition.singleValue = it + query.add(fromCondition) + } + this.to?.let { + val toCondition = QueryCondition.StartedToDate() + toCondition.singleValue = it + query.add(toCondition) + } + return query + } /** * Returns whether or not the initial value should be added for the bankroll total @@ -276,7 +235,7 @@ class BankrollReportSetup(val bankroll: Bankroll? = null, val from: Date? = null /** * A TransactionBucket holds a list of _transactions and computes its amount sum */ -class TransactionBucket(useRate: Boolean = false) { +class TransactionBucket(var name: String, useRate: Boolean = false) { /** * Whether the bankroll rate should be used diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReportManager.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReportManager.kt new file mode 100644 index 00000000..9f68008f --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReportManager.kt @@ -0,0 +1,114 @@ +package net.pokeranalytics.android.calculus.bankroll + +import io.realm.Realm +import io.realm.RealmResults +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.async +import kotlinx.coroutines.launch +import net.pokeranalytics.android.model.realm.Bankroll +import net.pokeranalytics.android.model.realm.ComputableResult +import net.pokeranalytics.android.model.realm.Transaction +import timber.log.Timber +import java.util.* +import kotlin.coroutines.CoroutineContext + +object BankrollReportManager { + + val coroutineContext: CoroutineContext + get() = Dispatchers.Main + + private var reports: MutableMap = mutableMapOf() + + private var computableResults: RealmResults + private var bankrolls: RealmResults + private var transactions: RealmResults + + init { + + val realm = Realm.getDefaultInstance() + computableResults = realm.where(ComputableResult::class.java).findAll() + bankrolls = realm.where(Bankroll::class.java).findAll() + transactions = realm.where(Transaction::class.java).findAll() + + initializeListeners() + realm.close() + } + + /** + * Listens to all objects that might have an impact on any bankroll report + */ + private fun initializeListeners() { + + this.computableResults.addChangeListener { t, changeSet -> + val indexes = changeSet.changes.plus(changeSet.insertions).toList() + val bankrolls = indexes.mapNotNull { t[it]?.session?.bankroll }.toSet() + this.updateBankrolls(bankrolls) + } + this.bankrolls.addChangeListener { t, changeSet -> + val indexes = changeSet.changes.plus(changeSet.insertions).toList() + val bankrolls = indexes.mapNotNull { t[it] }.toSet() + this.updateBankrolls(bankrolls) + } + this.transactions.addChangeListener { t, changeSet -> + val indexes = changeSet.changes.plus(changeSet.insertions).toList() + val bankrolls = indexes.mapNotNull { t[it]?.bankroll }.toSet() + this.updateBankrolls(bankrolls) + } + } + + fun reportForBankroll(bankrollId: String?, handler: (BankrollReport) -> Unit) { + + // if the report exists, return it + val existingReport: BankrollReport? = this.reports[bankrollId] + if (existingReport != null) { + handler(existingReport) + return + } + + // otherwise compute it + GlobalScope.launch(coroutineContext) { + + var report: BankrollReport? = null + val scope = GlobalScope.async { + val s = Date() + Timber.d(">>>>> start computing bankroll...") + + val realm = Realm.getDefaultInstance() + + val setup = BankrollReportSetup(bankrollId) + report = BankrollCalculator.computeReport(realm, setup) + + realm.close() + + val e = Date() + val duration = (e.time - s.time) / 1000.0 + Timber.d(">>>>> ended in $duration seconds") + + } + scope.await() + report?.let { handler(it) } + + } + } + + /** + * Notifies the manager of cases not managed by RealmResults listener, such as deletions + */ + fun notifyBankrollReportImpact(bankrollId: String) { + this.reports.remove(bankrollId) + this.reports.remove(null) + } + + private fun updateBankrolls(bankrolls: Set) { + this.invalidateReport(bankrolls) + } + + private fun invalidateReport(bankrolls: Set) { + this.reports.remove(null) + bankrolls.forEach { br -> + this.reports.remove(br.id) + } + } + +} diff --git a/app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt b/app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt index 7716e745..b8358605 100644 --- a/app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt +++ b/app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt @@ -10,6 +10,7 @@ class ConfigurationException(message: String) : Exception(message) class EnumIdentifierNotFoundException(message: String) : Exception(message) class MisconfiguredSavableEnumException(message: String) : Exception(message) +class PAIllegalStateException(message: String) : Exception(message) sealed class PokerAnalyticsException(message: String) : Exception(message) { object FilterElementUnknownName : PokerAnalyticsException(message = "No filterElement name was found to identify the queryCondition") diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/BankrollActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/BankrollActivity.kt index 0f37c4d8..db9237b3 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/BankrollActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/BankrollActivity.kt @@ -37,47 +37,6 @@ class BankrollActivity : PokerAnalyticsActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_bankroll) -// this.computableResults = getRealm().where(ComputableResult::class.java).findAll() // ComputableResult are existing only if sessions are ended -// this.computableResults.addChangeListener { t, changeSet -> -// -// val bankrolls = mutableSetOf() -// val indexes = mutableSetOf() -// indexes.addAll(changeSet.changes.toList()) -// indexes.addAll(changeSet.insertions.toList()) -// indexes.addAll(changeSet.deletions.toList()) -// indexes.forEach { index -> -// t[index]?.session?.bankroll?.let { br -> -// bankrolls.add(br) -// } -// } -// this.computeBankrollReports(bankrolls) -// } -// this.bankrolls = getRealm().where(Bankroll::class.java).findAll() // ComputableResult are existing only if sessions are ended -// this.bankrolls.addChangeListener { _, changeSet -> -// -// -// -// -// -// } -// this.transactions = getRealm().where(Transaction::class.java).findAll() // ComputableResult are existing only if sessions are ended -// this.transactions.addChangeListener { t, changeSet -> -// -// val bankrolls = mutableSetOf() -// val indexes = mutableSetOf() -// indexes.addAll(changeSet.changes.toList()) -// indexes.addAll(changeSet.insertions.toList()) -// indexes.addAll(changeSet.deletions.toList()) -// indexes.forEach { index -> -// if (t.isNotEmpty()) { -// t[index]?.bankroll?.let { br -> -// bankrolls.add(br) -// } -// } -// } -// this.computeBankrollReports(bankrolls) -// } - } fun computeBankrollReports(bankrolls: Collection) { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt index ed11d47f..23cb64f8 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt @@ -2,6 +2,8 @@ package net.pokeranalytics.android.ui.activity.components enum class RequestCode(var value: Int) { DEFAULT(1), + BANKROLL_DETAILS(700), + BANKROLL_CREATE(701), NEW_SESSION(800), NEW_TRANSACTION(801), NEW_REPORT(802), diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt index ab2175f2..923695d5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt @@ -10,18 +10,22 @@ import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.ComputedStat import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.bankroll.BankrollReport +import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.LiveData +import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.EditableDataActivity import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource -import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment +import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable +import net.pokeranalytics.android.util.extensions.findById -class BankrollDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { +class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { companion object { @@ -32,27 +36,32 @@ class BankrollDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable */ fun newInstance(bankrollReport: BankrollReport): BankrollDetailsFragment { val fragment = BankrollDetailsFragment() - fragment.bankrollReport = bankrollReport + fragment.bankrollId = bankrollReport.setup.bankrollId +// fragment.bankrollReport = bankrollReport return fragment } } + private var bankrollId: String? = null + private lateinit var bankroll: Bankroll + + private var rows: ArrayList = ArrayList() private lateinit var bankrollAdapter: RowRepresentableAdapter - private lateinit var bankrollReport: BankrollReport +// private lateinit var bankrollReport: BankrollReport private var bankrollDetailsMenu: Menu? = null - private var rows: ArrayList = ArrayList() // Life Cycle override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + super.onCreateView(inflater, container, savedInstanceState) return inflater.inflate(R.layout.fragment_bankroll_details, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - initUI() initData() + initUI() } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -62,40 +71,35 @@ class BankrollDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable activity?.setResult(RESULT_OK, data) activity?.finish() } else { - updateMenuUI() + BankrollReportManager.reportForBankroll(this.bankrollId) { + updateUI(it) + } } } } - override fun adapterRows(): List? { - return rows + private fun updateUI(bankrollReport: BankrollReport) { + this.initRows(bankrollReport) + this.updateMenuUI(bankrollReport) + this.bankrollAdapter.notifyDataSetChanged() } - override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { - - } + /** + * Init data + */ + private fun initData() { - override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { - menu?.clear() - inflater?.inflate(R.menu.toolbar_comparison_chart, menu) - this.bankrollDetailsMenu = menu - updateMenuUI() - super.onCreateOptionsMenu(menu, inflater) - } + this.bankrollId?.let { id -> + this.bankroll = getRealm().findById(id) ?: throw PAIllegalStateException("Bankroll not found, id=$id") + } - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item!!.itemId) { - R.id.settings -> editBankroll() + BankrollReportManager.reportForBankroll(this.bankrollId) { + updateUI(it) } - return true - } - // Business + } - /** - * Init data - */ - private fun initData() { + private fun initRows(bankrollReport: BankrollReport) { rows.clear() @@ -105,23 +109,47 @@ class BankrollDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable val netComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.netResult) val netBankedComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.netBanked) - rows.add(CustomizableRowRepresentable(RowViewType.TITLE_VALUE, resId = R.string.bankroll, computedStat = totalComputedStat)) - rows.add(CustomizableRowRepresentable(RowViewType.TITLE_VALUE, resId = R.string.net_result, computedStat = netComputedStat)) - rows.add(CustomizableRowRepresentable(RowViewType.TITLE_VALUE, resId = R.string.net_banked, computedStat = netBankedComputedStat)) + rows.add( + CustomizableRowRepresentable( + RowViewType.TITLE_VALUE, + resId = R.string.bankroll, + computedStat = totalComputedStat + ) + ) + rows.add( + CustomizableRowRepresentable( + RowViewType.TITLE_VALUE, + resId = R.string.net_result, + computedStat = netComputedStat + ) + ) + rows.add( + CustomizableRowRepresentable( + RowViewType.TITLE_VALUE, + resId = R.string.net_banked, + computedStat = netBankedComputedStat + ) + ) if (bankrollReport.transactionBuckets.isNotEmpty()) { rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.operations)) bankrollReport.transactionBuckets.keys.forEach { key -> bankrollReport.transactionBuckets[key]?.let { transactionBucket -> - val typeName = transactionBucket.transactions.firstOrNull()?.type?.getDisplayName(requireContext()) + val typeName = transactionBucket.name val computedStat = ComputedStat(Stat.NET_RESULT, transactionBucket.total) - rows.add(CustomizableRowRepresentable(RowViewType.TITLE_VALUE, title = typeName, computedStat = computedStat)) + rows.add( + CustomizableRowRepresentable( + RowViewType.TITLE_VALUE, + title = typeName, + computedStat = computedStat + ) + ) } } } - } + /** * Init UI */ @@ -129,8 +157,6 @@ class BankrollDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable setDisplayHomeAsUpEnabled(true) - updateMenuUI() - bankrollAdapter = RowRepresentableAdapter(this, this) val viewManager = LinearLayoutManager(requireContext()) @@ -145,23 +171,52 @@ class BankrollDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable /** * Update menu UI */ - private fun updateMenuUI() { + private fun updateMenuUI(bankrollReport: BankrollReport) { if (bankrollReport.setup.virtualBankroll) { setToolbarTitle(getString(R.string.total)) bankrollDetailsMenu?.findItem(R.id.settings)?.isVisible = false } else { - setToolbarTitle(bankrollReport.setup.bankroll?.name) + setToolbarTitle(this.bankroll.name) bankrollDetailsMenu?.findItem(R.id.settings)?.isVisible = true } } + // StaticRowRepresentableDataSource + + override fun adapterRows(): List? { + return rows + } + + // RowRepresentableDelegate + + override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { + + } + + override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { + menu?.clear() + inflater?.inflate(R.menu.toolbar_comparison_chart, menu) + this.bankrollDetailsMenu = menu +// updateMenuUI() + super.onCreateOptionsMenu(menu, inflater) + } + + override fun onOptionsItemSelected(item: MenuItem?): Boolean { + when (item!!.itemId) { + R.id.settings -> editBankroll() + } + return true + } + + // Business + /** * Open Bankroll edit activity */ private fun editBankroll() { - EditableDataActivity.newInstanceForResult(this, LiveData.BANKROLL, bankrollReport.setup.bankroll?.id, REQUEST_CODE_EDIT) + EditableDataActivity.newInstanceForResult(this, LiveData.BANKROLL, this.bankrollId, REQUEST_CODE_EDIT) } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt index 58e954a9..0524f996 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt @@ -16,39 +16,34 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import net.pokeranalytics.android.R -import net.pokeranalytics.android.calculus.ComputedStat -import net.pokeranalytics.android.calculus.Stat -import net.pokeranalytics.android.calculus.bankroll.BankrollCalculator -import net.pokeranalytics.android.calculus.bankroll.BankrollReport -import net.pokeranalytics.android.calculus.bankroll.BankrollReportSetup +import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager 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.Bankroll import net.pokeranalytics.android.ui.activity.BankrollDetailsActivity import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.EditableDataActivity import net.pokeranalytics.android.ui.activity.GraphActivity +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.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.fragment.components.DeletableItemFragment import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType -import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable -import net.pokeranalytics.android.ui.view.rowrepresentable.GraphRow +import net.pokeranalytics.android.ui.view.rowrepresentable.* import net.pokeranalytics.android.util.extensions.sorted -import timber.log.Timber import java.util.* import kotlin.collections.ArrayList +interface BankrollRowRepresentable : RowRepresentable { + var bankrollId: String? +} + class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { companion object { - const val REQUEST_CODE_DETAILS = 100 - const val REQUEST_CODE_CREATE = 101 - /** * Create new instance */ @@ -61,14 +56,14 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour } private var rows: ArrayList = ArrayList() - private var bankrollReportForRow: HashMap = HashMap() + private var bankrollRowRepresentables: HashMap> = HashMap() private var lastItemClickedPosition: Int = 0 - private var lastItemClickedId: String = "" +// private var lastItemClickedId: String = "" private var deletedRow: RowRepresentable? = null private lateinit var bankrolls: RealmResults - override fun deletableItems() : List { + override fun deletableItems(): List { return this.bankrolls } @@ -85,21 +80,26 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour initData() } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) - if (requestCode == REQUEST_CODE_DETAILS && resultCode == Activity.RESULT_OK) { + if (requestCode == RequestCode.BANKROLL_DETAILS.value && resultCode == Activity.RESULT_OK) { val itemToDeleteId = data?.getStringExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName) itemToDeleteId?.let { id -> GlobalScope.launch(Dispatchers.Main) { delay(300) deleteItem(dataListAdapter, bankrolls, id) + + // update view + BankrollReportManager.notifyBankrollReportImpact(id) + dataListAdapter.notifyDataSetChanged() } } - } else if (requestCode == REQUEST_CODE_CREATE && resultCode == Activity.RESULT_OK) { + } else if (requestCode == RequestCode.BANKROLL_CREATE.value && resultCode == Activity.RESULT_OK) { //TODO: Refresh bankrolls initData() + } else { + dataListAdapter.notifyDataSetChanged() } } @@ -109,20 +109,19 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour } override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { + lastItemClickedPosition = position when (row) { + is BankrollRowRepresentable -> { + BankrollReportManager.reportForBankroll(row.bankrollId) { bankrollReport -> + +// lastItemClickedId = row.bankrollId ?: "" + BankrollDetailsActivity.newInstanceForResult(this, bankrollReport, RequestCode.BANKROLL_DETAILS.value) + } + } is GraphRow -> { val lineDataSet = row.dataSet as LineDataSet GraphActivity.newInstance(requireContext(), listOf(lineDataSet), title = getString(R.string.bankroll)) } - else -> { - if (bankrollReportForRow.containsKey(row)) { - bankrollReportForRow[row]?.let { bankrollReport -> - lastItemClickedPosition = position - lastItemClickedId = (row as? Identifiable)?.id ?: "" - BankrollDetailsActivity.newInstanceForResult(this, bankrollReport, REQUEST_CODE_DETAILS) - } - } - } } } @@ -137,49 +136,26 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour this.bankrolls = realm.sorted() rows.clear() - bankrollReportForRow.clear() - - GlobalScope.launch { - - launch(Dispatchers.Main) { - // TODO: Improve that - // We are in the main thread... + // Virtual bankroll + val graphRow = BankrollGraphRow() + rows.add(0, graphRow) + val mainRow = BankrollMainRow() + rows.add(mainRow) - val startDate = Date() + bankrollRowRepresentables[null] = listOf(graphRow, mainRow) - // Graph - val globalBankrollReportSetup = BankrollReportSetup() - val globalBankrollReport = BankrollCalculator.computeReport(getRealm(), globalBankrollReportSetup) - rows.add(0, GraphRow(dataSet = globalBankrollReport.lineDataSet(requireContext()))) - rows.add(globalBankrollReport) - bankrollReportForRow[globalBankrollReport] = globalBankrollReport + // Bankrolls + rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.bankrolls)) - // Bankrolls - rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.bankrolls)) - - Timber.d("initData: ${System.currentTimeMillis() - startDate.time}ms") - -// val bankrolls = LiveData.Bankroll.items(getRealm()) as RealmResults - - bankrolls.forEach { bankroll -> - val bankrollReportSetup = BankrollReportSetup(bankroll) - val bankrollReport = BankrollCalculator.computeReport(getRealm(), bankrollReportSetup) - val computedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.total) - val row = - CustomizableRowRepresentable(RowViewType.TITLE_VALUE_ARROW, title = bankroll.name, computedStat = computedStat, isSelectable = true) - row.id = bankroll.id - - rows.add(row) - bankrollReportForRow[row] = bankrollReport - } - - if (!isDetached) { - dataListAdapter.notifyDataSetChanged() - } - } + bankrolls.forEach { bankroll -> + val row = BankrollTotalRow(bankroll.id, bankroll.name) + rows.add(row) + bankrollRowRepresentables[bankroll.id] = listOf(row) } + dataListAdapter.notifyDataSetChanged() + } /** @@ -200,13 +176,18 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour } addButton.setOnClickListener { - EditableDataActivity.newInstanceForResult(this@BankrollFragment, dataType = LiveData.BANKROLL, primaryKey = null, requestCode = REQUEST_CODE_CREATE) + EditableDataActivity.newInstanceForResult( + this@BankrollFragment, + dataType = LiveData.BANKROLL, + primaryKey = null, + requestCode = RequestCode.BANKROLL_CREATE.value + ) } } - override fun updateUIAfterDeletion(itemPosition: Int) { - lastItemClickedPosition = rows.indexOfFirst { if (it is Identifiable) it.id == lastItemClickedId else false } - deletedRow = rows.find { if (it is Identifiable) it.id == lastItemClickedId else false } + override fun updateUIAfterDeletion(itemId: String, itemPosition: Int) { + lastItemClickedPosition = rows.indexOfFirst { if (it is BankrollRowRepresentable) it.bankrollId == itemId else false } + deletedRow = rows.find { if (it is BankrollRowRepresentable) it.bankrollId == itemId else false } rows.removeAt(lastItemClickedPosition) dataListAdapter.notifyItemRemoved(lastItemClickedPosition) } @@ -217,12 +198,14 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour // We are recreating a Bankroll report because the last one is invalid => the bankroll of the setup has been deleted deletedRow?.let { row -> - val bankrollReportSetup = BankrollReportSetup(newItem as Bankroll) - val bankrollReport = BankrollCalculator.computeReport(getRealm(), bankrollReportSetup) - bankrollReportForRow[row] = bankrollReport +// val bankrollReportSetup = BankrollReportSetup(newItem as Bankroll) +// val bankrollReport = BankrollCalculator.computeReport(getRealm(), bankrollReportSetup) +// bankrollReportForRow[row] = bankrollReport rows.add(lastItemClickedPosition, row) - dataListAdapter.notifyItemInserted(lastItemClickedPosition) + dataListAdapter.notifyDataSetChanged() // update both virtual + ex-deleted + +// dataListAdapter.notifyItemInserted(lastItemClickedPosition) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt index 3d026bfa..cd33cc31 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt @@ -33,6 +33,7 @@ import net.pokeranalytics.android.ui.interfaces.FilterableType 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 java.text.SimpleDateFormat import java.util.* @@ -274,12 +275,12 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { */ private fun createNewSession(isTournament: Boolean) { -// val sessionCount = this.feedSessionAdapter.realmResults.size -// if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG -// Toast.makeText(context, "Please subscribe!", Toast.LENGTH_LONG).show() -// BillingActivity.newInstanceForResult(requireContext()) -// return -// } + val sessionCount = this.feedSessionAdapter.realmResults.size + if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG + Toast.makeText(context, "Please subscribe!", Toast.LENGTH_LONG).show() + BillingActivity.newInstance(requireContext()) + return + } if (Date().after(betaLimitDate)) { this.showEndOfBetaMessage() diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt index aefaa32d..0f1a2da3 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt @@ -10,6 +10,7 @@ import androidx.interpolator.view.animation.FastOutSlowInInterpolator import androidx.recyclerview.widget.DiffUtil import kotlinx.android.synthetic.main.fragment_session.* import net.pokeranalytics.android.R +import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.extensions.SessionState import net.pokeranalytics.android.model.extensions.getState @@ -344,6 +345,9 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate { * Delete a session */ private fun deleteSession() { + currentSession.bankroll?.id?.let { id -> + BankrollReportManager.notifyBankrollReportImpact(id) + } currentSession.delete() activity?.finish() } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt index 71cea8c1..07595c6d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt @@ -92,7 +92,7 @@ abstract class DeletableItemFragment : RealmFragment() { itemToDelete.deleteFromRealm() } itemHasBeenReInserted = false - updateUIAfterDeletion(itemPosition) + updateUIAfterDeletion(itemId, itemPosition) showUndoSnackBar() } else { dataListAdapter.notifyItemChanged(itemPosition) @@ -133,7 +133,7 @@ abstract class DeletableItemFragment : RealmFragment() { /** * Called once the object has been deleted */ - open fun updateUIAfterDeletion(itemPosition: Int) { + open fun updateUIAfterDeletion(itemId: String, itemPosition: Int) { dataListAdapter.notifyItemRemoved(itemPosition) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt index a7ee9216..1234528b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt @@ -128,6 +128,8 @@ open class DataManagerFragment : RealmFragment() { */ protected open fun deleteData() { + this.willDeleteData() + val realm = this.getRealm() if (this.item.isValidForDelete(realm)) { @@ -145,6 +147,8 @@ open class DataManagerFragment : RealmFragment() { } } + open fun willDeleteData() { } + /** * Finish the activity with a result */ diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/TransactionDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/TransactionDataFragment.kt index 789c00ed..9d60fe96 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/TransactionDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/TransactionDataFragment.kt @@ -6,6 +6,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Transaction import net.pokeranalytics.android.model.realm.TransactionType @@ -115,4 +116,11 @@ class TransactionDataFragment : EditableDataFragment(), StaticRowRepresentableDa } } + override fun willDeleteData() { + super.willDeleteData() + this.transaction?.bankroll?.id?.let { id -> + BankrollReportManager.notifyBankrollReportImpact(id) + } + } + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt index 12ccaece..42e6da6f 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt @@ -14,10 +14,7 @@ import androidx.core.widget.ContentLoadingProgressBar import androidx.recyclerview.widget.RecyclerView import com.github.mikephil.charting.charts.BarChart import com.github.mikephil.charting.charts.LineChart -import com.github.mikephil.charting.data.BarData -import com.github.mikephil.charting.data.BarDataSet -import com.github.mikephil.charting.data.LineData -import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.data.* import com.google.android.material.chip.Chip import com.google.android.material.chip.ChipGroup import kotlinx.android.synthetic.main.row_feed_session.view.* @@ -25,7 +22,7 @@ import kotlinx.android.synthetic.main.row_transaction.view.* import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.ComputedStat import net.pokeranalytics.android.calculus.Stat -import net.pokeranalytics.android.calculus.bankroll.BankrollReport +import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager import net.pokeranalytics.android.model.realm.CustomField import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Transaction @@ -34,6 +31,7 @@ import net.pokeranalytics.android.ui.extensions.ChipGroupExtension import net.pokeranalytics.android.ui.extensions.addCircleRipple import net.pokeranalytics.android.ui.extensions.px import net.pokeranalytics.android.ui.extensions.setTextFormat +import net.pokeranalytics.android.ui.fragment.BankrollRowRepresentable import net.pokeranalytics.android.ui.graph.AxisFormatting import net.pokeranalytics.android.ui.graph.setStyle import net.pokeranalytics.android.ui.view.rowrepresentable.* @@ -139,93 +137,118 @@ enum class RowViewType(private var layoutRes: Int) { inner class RowViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) { - if (row is CustomizableRowRepresentable) { + when (row) { - // Customizable Row + is BankrollRowRepresentable -> { - // Title - itemView.findViewById(R.id.title)?.let { - it.text = row.localizedTitle(itemView.context) - } - - // Value - itemView.findViewById(R.id.value)?.let { - if (row.computedStat != null) { - val format = row.computedStat!!.format() - it.setTextFormat(format, itemView.context) - } else if (row.value != null) { - it.text = row.value + // Title + itemView.findViewById(R.id.title)?.let { + it.text = row.localizedTitle(itemView.context) } - } - // Listener - row.isSelectable?.let { isSelectable -> - if (isSelectable) { - val listener = View.OnClickListener { - adapter.delegate?.onRowSelected(position, row) + BankrollReportManager.reportForBankroll(row.bankrollId) { report -> + + itemView.findViewById(R.id.title)?.let { + it.text = row.localizedTitle(itemView.context) } - itemView.findViewById(R.id.container)?.setOnClickListener(listener) + val computedStat = ComputedStat(Stat.NET_RESULT, report.total) + itemView.findViewById(R.id.value)?.setTextFormat(computedStat.format(), itemView.context) } - } - } else { + val listener = View.OnClickListener { + adapter.delegate?.onRowSelected(position, row) + } + itemView.findViewById(R.id.container)?.setOnClickListener(listener) + } + is CustomizableRowRepresentable -> { - // Classic row + // Customizable Row - // Title - itemView.findViewById(R.id.title)?.let { - if (row.resId != null) { + // Title + itemView.findViewById(R.id.title)?.let { it.text = row.localizedTitle(itemView.context) - } else { - it.text = row.getDisplayName(itemView.context) } - } - // Value - itemView.findViewById(R.id.value)?.let { - it.text = adapter.dataSource.stringForRow(row, itemView.context) - } + // Value + itemView.findViewById(R.id.value)?.let { + if (row.computedStat != null) { + val format = row.computedStat!!.format() + it.setTextFormat(format, itemView.context) + } else if (row.value != null) { + it.text = row.value + } + } - // Icon - itemView.findViewById(R.id.icon)?.let { imageView -> - imageView.setImageDrawable(null) - row.imageRes?.let { imageRes -> - imageView.setImageResource(imageRes) + // Listener + row.isSelectable?.let { isSelectable -> + if (isSelectable) { + val listener = View.OnClickListener { + adapter.delegate?.onRowSelected(position, row) + } + itemView.findViewById(R.id.container)?.setOnClickListener(listener) + } } + } + else -> { - // Action - itemView.findViewById(R.id.action)?.let { imageView -> - imageView.setImageDrawable(null) - row.imageRes?.let { imageRes -> - imageView.visibility = View.VISIBLE - imageView.setImageResource(imageRes) + // Classic row + + // Title + itemView.findViewById(R.id.title)?.let { + if (row.resId != null) { + it.text = row.localizedTitle(itemView.context) + } else { + it.text = row.getDisplayName(itemView.context) + } } - row.imageTint?.let { color -> - imageView.setColorFilter(ContextCompat.getColor(imageView.context, color)) + + // Value + itemView.findViewById(R.id.value)?.let { + it.text = adapter.dataSource.stringForRow(row, itemView.context) } - if (row.imageClickable == true) { - imageView.addCircleRipple() - imageView.setOnClickListener { - adapter.delegate?.onRowSelected(position, row, true) + + // Icon + itemView.findViewById(R.id.icon)?.let { imageView -> + imageView.setImageDrawable(null) + row.imageRes?.let { imageRes -> + imageView.setImageResource(imageRes) } - } else { - imageView.setBackgroundResource(0) } - } - // Listener - val listener = View.OnClickListener { - itemView.findViewById(R.id.switchView)?.let { - if (adapter.dataSource.isEnabled(row)) { - it.isChecked = !it.isChecked + // Action + itemView.findViewById(R.id.action)?.let { imageView -> + imageView.setImageDrawable(null) + row.imageRes?.let { imageRes -> + imageView.visibility = View.VISIBLE + imageView.setImageResource(imageRes) + } + row.imageTint?.let { color -> + imageView.setColorFilter(ContextCompat.getColor(imageView.context, color)) + } + if (row.imageClickable == true) { + imageView.addCircleRipple() + imageView.setOnClickListener { + adapter.delegate?.onRowSelected(position, row, true) + } + } else { + imageView.setBackgroundResource(0) + } + } + + // Listener + val listener = View.OnClickListener { + itemView.findViewById(R.id.switchView)?.let { + if (adapter.dataSource.isEnabled(row)) { + it.isChecked = !it.isChecked + } + } ?: run { + adapter.delegate?.onRowSelected(position, row) } - } ?: run { - adapter.delegate?.onRowSelected(position, row) } - } - itemView.findViewById(R.id.container)?.setOnClickListener(listener) + itemView.findViewById(R.id.container)?.setOnClickListener(listener) + } } // Switch @@ -346,43 +369,52 @@ enum class RowViewType(private var layoutRes: Int) { /** * Display a graph */ - inner class GraphViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), - BindableHolder { - override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) { + inner class GraphViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { - if (row is GraphRow) { + private fun loadWithDataSet(dataSet: DataSet<*>) { + val context = itemView.context - row.dataSet?.let { dataSet -> + val chartView = when (dataSet) { + is LineDataSet -> { + val lineChart = LineChart(context) + lineChart.data = LineData(dataSet) + lineChart + } + is BarDataSet -> { + val barChart = BarChart(context) + barChart.data = BarData(dataSet) + barChart + } + else -> null + } - val context = itemView.context + itemView.findViewById(R.id.chartContainer)?.let { + it.removeAllViews() + it.addView(chartView) + } - val chartView = when (dataSet) { - is LineDataSet -> { - val lineChart = LineChart(context) - lineChart.data = LineData(dataSet) - lineChart - } - is BarDataSet -> { - val barChart = BarChart(context) - barChart.data = BarData(dataSet) - barChart - } - else -> null - } + chartView?.let { + chartView.setStyle(true, AxisFormatting.DEFAULT, context) + chartView.setTouchEnabled(false) + } - itemView.findViewById(R.id.chartContainer)?.let { - it.removeAllViews() - it.addView(chartView) - } + } - chartView?.let { - chartView.setStyle(true, AxisFormatting.DEFAULT, context) - chartView.setTouchEnabled(false) - } + override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) { -// chartView.highlightValue((entries.size - 1).toFloat(), 0) + when (row) { + is BankrollGraphRow -> { + BankrollReportManager.reportForBankroll(row.bankrollId) { report -> + val dataSet = report.lineDataSet(itemView.context) + row.dataSet = dataSet + loadWithDataSet(dataSet) + } + } + is GraphRow -> { + row.dataSet?.let { dataSet -> + loadWithDataSet(dataSet) + } } - } // Listener @@ -400,22 +432,27 @@ enum class RowViewType(private var layoutRes: Int) { BindableHolder { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) { - if (row is BankrollReport) { + if (row is BankrollRowRepresentable) { + + BankrollReportManager.reportForBankroll(row.bankrollId) { report -> + + itemView.findViewById(R.id.stat1Value)?.let { + val formattedStat = ComputedStat(Stat.NET_RESULT, report.total).format() + it.setTextFormat(formattedStat, itemView.context) + } + itemView.findViewById(R.id.stat2Value)?.let { + val riskOfRuin = report.riskOfRuin ?: 0.0 + val formattedStat = ComputedStat(Stat.RISK_OF_RUIN, riskOfRuin).format() + it.setTextFormat(formattedStat, itemView.context) + } + } + itemView.findViewById(R.id.stat1Name)?.let { it.text = itemView.context.getString(R.string.total) } - itemView.findViewById(R.id.stat1Value)?.let { - val formattedStat = ComputedStat(Stat.NET_RESULT, row.total).format() - it.setTextFormat(formattedStat, itemView.context) - } itemView.findViewById(R.id.stat2Name)?.let { it.text = itemView.context.getString(R.string.risk_of_ruin) } - itemView.findViewById(R.id.stat2Value)?.let { - val riskOfRuin = row.riskOfRuin ?: 0.0 - val formattedStat = ComputedStat(Stat.RISK_OF_RUIN, riskOfRuin).format() - it.setTextFormat(formattedStat, itemView.context) - } val listener = View.OnClickListener { adapter.delegate?.onRowSelected(position, row) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/BankrollMainRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/BankrollMainRow.kt new file mode 100644 index 00000000..1e42445f --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/BankrollMainRow.kt @@ -0,0 +1,12 @@ +package net.pokeranalytics.android.ui.view.rowrepresentable + +import net.pokeranalytics.android.ui.fragment.BankrollRowRepresentable +import net.pokeranalytics.android.ui.view.RowViewType + +class BankrollMainRow : BankrollRowRepresentable { + + override var bankrollId: String? = null + + override val viewType: Int = RowViewType.LEGEND_DEFAULT.ordinal + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/CustomizableRowRepresentable.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/CustomizableRowRepresentable.kt index 3cdc0ace..84d223f6 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/CustomizableRowRepresentable.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/CustomizableRowRepresentable.kt @@ -3,9 +3,20 @@ package net.pokeranalytics.android.ui.view.rowrepresentable import android.content.Context import net.pokeranalytics.android.calculus.ComputedStat import net.pokeranalytics.android.model.interfaces.Identifiable +import net.pokeranalytics.android.ui.fragment.BankrollRowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType +class BankrollTotalRow(override var bankrollId: String?, var name: String) : BankrollRowRepresentable { + + override val viewType: Int = RowViewType.TITLE_VALUE_ARROW.ordinal + + override fun localizedTitle(context: Context): String { + return name + } + +} + /** * A class to display a titleResId (and a value) as a Row Representable object */ diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/GraphRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/GraphRow.kt index 7af17e6b..3f8f185b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/GraphRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/GraphRow.kt @@ -3,11 +3,18 @@ package net.pokeranalytics.android.ui.view.rowrepresentable import com.github.mikephil.charting.data.DataSet import net.pokeranalytics.android.calculus.Report import net.pokeranalytics.android.calculus.Stat +import net.pokeranalytics.android.ui.fragment.BankrollRowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType -class GraphRow(var dataSet: DataSet<*>?, var title: String? = null, var report: Report? = null, var stat: Stat? = null) : RowRepresentable { +class BankrollGraphRow : GraphRow(null, null, null, null), BankrollRowRepresentable { + + override var bankrollId: String? = null + +} + +open class GraphRow(var dataSet: DataSet<*>? = null, var title: String? = null, var report: Report? = null, var stat: Stat? = null) : RowRepresentable { override val viewType: Int get() = RowViewType.GRAPH.ordinal From 01914614e18f34e3fb7e24edd36debdc857c8e9e Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 11 Jun 2019 18:10:04 +0200 Subject: [PATCH 091/197] cleanup comments --- .../android/ui/fragment/BankrollFragment.kt | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt index 0524f996..97d98541 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt @@ -58,7 +58,6 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour private var rows: ArrayList = ArrayList() private var bankrollRowRepresentables: HashMap> = HashMap() private var lastItemClickedPosition: Int = 0 -// private var lastItemClickedId: String = "" private var deletedRow: RowRepresentable? = null private lateinit var bankrolls: RealmResults @@ -113,8 +112,6 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour when (row) { is BankrollRowRepresentable -> { BankrollReportManager.reportForBankroll(row.bankrollId) { bankrollReport -> - -// lastItemClickedId = row.bankrollId ?: "" BankrollDetailsActivity.newInstanceForResult(this, bankrollReport, RequestCode.BANKROLL_DETAILS.value) } } @@ -132,8 +129,7 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour */ private fun initData() { - val realm = getRealm() - this.bankrolls = realm.sorted() + this.bankrolls = getRealm().sorted() rows.clear() @@ -193,19 +189,9 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour } override fun updateUIAfterUndoDeletion(newItem: RealmObject) { - - // TODO: Improve that - // We are recreating a Bankroll report because the last one is invalid => the bankroll of the setup has been deleted - deletedRow?.let { row -> -// val bankrollReportSetup = BankrollReportSetup(newItem as Bankroll) -// val bankrollReport = BankrollCalculator.computeReport(getRealm(), bankrollReportSetup) -// bankrollReportForRow[row] = bankrollReport - rows.add(lastItemClickedPosition, row) dataListAdapter.notifyDataSetChanged() // update both virtual + ex-deleted - -// dataListAdapter.notifyItemInserted(lastItemClickedPosition) } } From 9a3cd3d7161b15356a2845c95461068ddef98f61 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 11 Jun 2019 19:44:37 +0200 Subject: [PATCH 092/197] Fixes issue with row selection + graph --- .../android/PokerAnalyticsApplication.kt | 2 +- .../net/pokeranalytics/android/calculus/Report.kt | 5 +++-- .../net/pokeranalytics/android/calculus/Stat.kt | 9 +++++++-- .../android/calculus/bankroll/BankrollReport.kt | 13 +++++++------ .../calculus/bankroll/BankrollReportManager.kt | 9 ++++++--- .../android/model/interfaces/Dated.kt | 4 +++- .../android/model/interfaces/Manageable.kt | 1 + .../android/model/interfaces/Timed.kt | 10 +++++++--- .../pokeranalytics/android/model/realm/Session.kt | 6 +++--- .../android/model/realm/Transaction.kt | 12 ++++++++---- .../android/ui/fragment/BankrollFragment.kt | 13 ++++++++----- .../android/ui/fragment/StatisticsFragment.kt | 2 +- .../android/ui/graph/GraphUnderlyingEntry.kt | 4 ++-- .../pokeranalytics/android/ui/view/RowViewType.kt | 4 ++-- 14 files changed, 59 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index 1b81d955..35ea4536 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -60,7 +60,7 @@ class PokerAnalyticsApplication : Application() { if (BuildConfig.DEBUG) { Timber.d("UserPreferences.defaultCurrency: ${UserDefaults.currency.symbol}") - this.createFakeSessions() +// this.createFakeSessions() } Patcher.patchAll(this.applicationContext) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt index f4b61d7f..63501b46 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt @@ -7,7 +7,8 @@ import io.realm.RealmResults import net.pokeranalytics.android.R import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition -import net.pokeranalytics.android.model.interfaces.Timed +import net.pokeranalytics.android.model.interfaces.GraphIdentifiableEntry +//import net.pokeranalytics.android.model.interfaces.Timed import net.pokeranalytics.android.model.realm.ComputableResult import net.pokeranalytics.android.model.realm.Filter import net.pokeranalytics.android.model.realm.SessionSet @@ -196,7 +197,7 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu /** * Adds a value to the evolution values */ - fun addEvolutionValue(value: Double, duration: Double? = null, stat: Stat, data: Timed) { + fun addEvolutionValue(value: Double, duration: Double? = null, stat: Stat, data: GraphIdentifiableEntry) { val point = if (duration != null) { Point(duration, y = value, data = data.objectIdentifier) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt index 2b8a30c8..ec9e50a7 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt @@ -159,10 +159,15 @@ enum class Stat(override var uniqueIdentifier: Int) : IntIdentifiable, RowRepres HOURLY_DURATION, AVERAGE_HOURLY_DURATION, MAXIMUM_DURATION -> { return TextFormat(value.formattedHourlyDuration()) } // red/green percentages - WIN_RATIO, ROI, RISK_OF_RUIN -> { + WIN_RATIO, ROI -> { val color = if (value * 100 >= this.threshold) R.color.green else R.color.red return TextFormat("${(value * 100).formatted()}%", color) - } // white amountsr + } + RISK_OF_RUIN -> { + val color = if (value * 100 <= this.threshold) R.color.green else R.color.red + return TextFormat("${(value * 100).formatted()}%", color) + } + // white amountsr AVERAGE_BUYIN, STANDARD_DEVIATION, STANDARD_DEVIATION_HOURLY, STANDARD_DEVIATION_BB_PER_100_HANDS -> { return TextFormat(value.toCurrency(currency)) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt index b6c079d6..f3bbe059 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt @@ -4,9 +4,10 @@ import android.content.Context import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.data.LineDataSet import io.realm.Realm +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition -import net.pokeranalytics.android.model.interfaces.DatedValue +import net.pokeranalytics.android.model.interfaces.DatedGraphEntry import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Transaction import net.pokeranalytics.android.ui.graph.DataSetFactory @@ -116,12 +117,12 @@ class BankrollReport(var setup: BankrollReportSetup) { /** * The list of dated items used for the graph */ - private var evolutionItems: MutableList = mutableListOf() + private var evolutionItems: MutableList = mutableListOf() /** * Adds a list of dated items to the evolution items used to get the bankroll graph */ - fun addDatedItems(items: Collection) { + fun addDatedItems(items: Collection) { this.evolutionItems.addAll(items) } @@ -143,7 +144,7 @@ class BankrollReport(var setup: BankrollReportSetup) { bucket.addTransaction(transaction) } ?: run { - throw IllegalStateException("Transaction has no type") + throw PAIllegalStateException("Transaction has no type") } } @@ -162,7 +163,7 @@ class BankrollReport(var setup: BankrollReportSetup) { var total = this.initial this.evolutionItems.forEach { total += it.amount - val point = BRGraphPoint(total, it.date, it) + val point = BRGraphPoint(total, it.date, it.objectIdentifier) this.evolutionPoints.add(point) } @@ -276,6 +277,6 @@ class TransactionBucket(var name: String, useRate: Boolean = false) { data class BRGraphPoint(var value: Double, var date: Date, var data: Any? = null) { - var variation: Double = 0.0 +// var variation: Double = 0.0 } diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReportManager.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReportManager.kt index 9f68008f..a6fd8917 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReportManager.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReportManager.kt @@ -70,7 +70,7 @@ object BankrollReportManager { GlobalScope.launch(coroutineContext) { var report: BankrollReport? = null - val scope = GlobalScope.async { + val coroutine = GlobalScope.async { val s = Date() Timber.d(">>>>> start computing bankroll...") @@ -86,8 +86,11 @@ object BankrollReportManager { Timber.d(">>>>> ended in $duration seconds") } - scope.await() - report?.let { handler(it) } + coroutine.await() + + report?.let { + handler(it) + } } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Dated.kt b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Dated.kt index 86cea43b..bb20862a 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Dated.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Dated.kt @@ -12,4 +12,6 @@ interface DatedValue : Dated { var amount: Double -} \ No newline at end of file +} + +interface DatedGraphEntry : DatedValue, GraphIdentifiableEntry \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt index 05624c3a..26ebd99a 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt @@ -55,6 +55,7 @@ interface Identifiable : RealmModel { * A unique uniqueIdentifier getter */ var id: String + } /** diff --git a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt index 1123f298..31ca5fe9 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt @@ -4,7 +4,13 @@ import net.pokeranalytics.android.ui.graph.GraphUnderlyingEntry import net.pokeranalytics.android.ui.graph.ObjectIdentifier import java.util.* -interface Timed : GraphUnderlyingEntry, Identifiable { +interface GraphIdentifiableEntry : GraphUnderlyingEntry, Identifiable { + + val objectIdentifier : ObjectIdentifier + +} + +interface Timed : GraphIdentifiableEntry { fun startDate() : Date? @@ -30,6 +36,4 @@ interface Timed : GraphUnderlyingEntry, Identifiable { val hourlyDuration: Double get() = this.netDuration / 3600000.0 - val objectIdentifier : ObjectIdentifier - } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 088ac609..aa97a132 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -46,7 +46,7 @@ import kotlin.collections.ArrayList typealias BB = Double open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDataSource, RowRepresentable, Timed, - TimeFilterable, Filterable, DatedValue { + TimeFilterable, Filterable, DatedGraphEntry { enum class Type { CASH_GAME, @@ -791,7 +791,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } return NULL_TEXT } - else -> throw UnmanagedRowRepresentableException("Unmanaged row = ${row}") + else -> throw UnmanagedRowRepresentableException("Unmanaged row = $row") } } @@ -1138,7 +1138,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat DefaultLegendValues(this.entryTitle(context), left, right) } else -> { - super.legendValues(stat, entry, style, groupName, context) + super.legendValues(stat, entry, style, groupName, context) } } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt index 748b3e84..66432946 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt @@ -13,7 +13,7 @@ import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.interfaces.* import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.fragment.GraphFragment -import net.pokeranalytics.android.ui.graph.GraphUnderlyingEntry +import net.pokeranalytics.android.ui.graph.ObjectIdentifier import net.pokeranalytics.android.ui.view.DefaultLegendValues import net.pokeranalytics.android.ui.view.LegendContent import net.pokeranalytics.android.ui.view.RowRepresentable @@ -26,8 +26,8 @@ import java.util.* import kotlin.collections.ArrayList -open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSource, RowRepresentable, TimeFilterable, Filterable, DatedValue, - GraphUnderlyingEntry { +open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSource, RowRepresentable, TimeFilterable, + Filterable, DatedGraphEntry { companion object { @@ -134,7 +134,10 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo return SaveValidityStatus.VALID } - // GraphUnderlyingEntry + // GraphIdentifiableEntry + + override val objectIdentifier: ObjectIdentifier + get() = ObjectIdentifier(this.id, Transaction::class.java) override fun entryTitle(context: Context): String { return DateFormat.getDateInstance(DateFormat.SHORT).format(this.date) @@ -158,4 +161,5 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo return DefaultLegendValues(this.entryTitle(context), entryValue, totalStatValue, leftName = leftName) } + } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt index 97d98541..6cb4fb42 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt @@ -31,7 +31,10 @@ import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.fragment.components.DeletableItemFragment import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType -import net.pokeranalytics.android.ui.view.rowrepresentable.* +import net.pokeranalytics.android.ui.view.rowrepresentable.BankrollGraphRow +import net.pokeranalytics.android.ui.view.rowrepresentable.BankrollMainRow +import net.pokeranalytics.android.ui.view.rowrepresentable.BankrollTotalRow +import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.util.extensions.sorted import java.util.* import kotlin.collections.ArrayList @@ -110,15 +113,15 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { lastItemClickedPosition = position when (row) { + is BankrollGraphRow -> { + val lineDataSet = row.dataSet as LineDataSet + GraphActivity.newInstance(requireContext(), listOf(lineDataSet), title = getString(R.string.bankroll)) + } is BankrollRowRepresentable -> { BankrollReportManager.reportForBankroll(row.bankrollId) { bankrollReport -> BankrollDetailsActivity.newInstanceForResult(this, bankrollReport, RequestCode.BANKROLL_DETAILS.value) } } - is GraphRow -> { - val lineDataSet = row.dataSet as LineDataSet - GraphActivity.newInstance(requireContext(), listOf(lineDataSet), title = getString(R.string.bankroll)) - } } } 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 dfcc828a..18d92fdd 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 @@ -32,7 +32,7 @@ import kotlin.coroutines.CoroutineContext class StatisticsFragment : FilterableFragment() { - val coroutineContext: CoroutineContext + private val coroutineContext: CoroutineContext get() = Dispatchers.Main private lateinit var tableReportFragment: ComposableTableReportFragment diff --git a/app/src/main/java/net/pokeranalytics/android/ui/graph/GraphUnderlyingEntry.kt b/app/src/main/java/net/pokeranalytics/android/ui/graph/GraphUnderlyingEntry.kt index 897ff3f9..01d9ead9 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/graph/GraphUnderlyingEntry.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/graph/GraphUnderlyingEntry.kt @@ -3,13 +3,13 @@ package net.pokeranalytics.android.ui.graph import android.content.Context import com.github.mikephil.charting.data.Entry import net.pokeranalytics.android.calculus.Stat -import net.pokeranalytics.android.model.interfaces.Timed +import net.pokeranalytics.android.model.interfaces.GraphIdentifiableEntry import net.pokeranalytics.android.ui.fragment.GraphFragment import net.pokeranalytics.android.ui.view.DefaultLegendValues import net.pokeranalytics.android.ui.view.LegendContent import net.pokeranalytics.android.util.TextFormat -class ObjectIdentifier(var id: String, var clazz: Class) { +class ObjectIdentifier(var id: String, var clazz: Class) { } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt index 42e6da6f..9a453d39 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt @@ -428,8 +428,8 @@ enum class RowViewType(private var layoutRes: Int) { /** * Display a legend */ - inner class LegendDefaultViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), - BindableHolder { + inner class LegendDefaultViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { + override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) { if (row is BankrollRowRepresentable) { From 4728074bc2f1be74ce00090071cd3967afeb775e Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 11 Jun 2019 19:45:16 +0200 Subject: [PATCH 093/197] Bumps to version 37 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 91d6b38d..4600a2b6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,8 +29,8 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 35 - versionName "2.0" + versionCode 37 + versionName "2.0.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From b20135e95ff00279d97691b13148b19154fa7b76 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Jun 2019 10:23:20 +0200 Subject: [PATCH 094/197] Fixes bankroll details title --- .../android/ui/fragment/BankrollDetailsFragment.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt index 923695d5..05f014f6 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt @@ -80,7 +80,7 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc private fun updateUI(bankrollReport: BankrollReport) { this.initRows(bankrollReport) - this.updateMenuUI(bankrollReport) + this.updateMenuUI() this.bankrollAdapter.notifyDataSetChanged() } @@ -156,6 +156,7 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc private fun initUI() { setDisplayHomeAsUpEnabled(true) + this.updateMenuUI() bankrollAdapter = RowRepresentableAdapter(this, this) @@ -171,9 +172,9 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc /** * Update menu UI */ - private fun updateMenuUI(bankrollReport: BankrollReport) { + private fun updateMenuUI() { - if (bankrollReport.setup.virtualBankroll) { + if (this.bankrollId == null) { setToolbarTitle(getString(R.string.total)) bankrollDetailsMenu?.findItem(R.id.settings)?.isVisible = false } else { @@ -199,7 +200,7 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc menu?.clear() inflater?.inflate(R.menu.toolbar_comparison_chart, menu) this.bankrollDetailsMenu = menu -// updateMenuUI() + updateMenuUI() super.onCreateOptionsMenu(menu, inflater) } From f327eab7baa2be3b4ebaf00c99a05862183275ec Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Jun 2019 10:27:44 +0200 Subject: [PATCH 095/197] Put local code into RequestCode --- .../android/ui/activity/components/Codes.kt | 1 + .../android/ui/fragment/BankrollDetailsFragment.kt | 12 +++--------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt index 23cb64f8..c8ada486 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt @@ -4,6 +4,7 @@ enum class RequestCode(var value: Int) { DEFAULT(1), BANKROLL_DETAILS(700), BANKROLL_CREATE(701), + BANKROLL_EDIT(702), NEW_SESSION(800), NEW_TRANSACTION(801), NEW_REPORT(802), diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt index 05f014f6..533b8c7b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt @@ -16,6 +16,7 @@ import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.EditableDataActivity +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.adapter.StaticRowRepresentableDataSource @@ -29,15 +30,9 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc companion object { - const val REQUEST_CODE_EDIT = 1000 - - /** - * Create new instance - */ fun newInstance(bankrollReport: BankrollReport): BankrollDetailsFragment { val fragment = BankrollDetailsFragment() fragment.bankrollId = bankrollReport.setup.bankrollId -// fragment.bankrollReport = bankrollReport return fragment } } @@ -47,7 +42,6 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc private var rows: ArrayList = ArrayList() private lateinit var bankrollAdapter: RowRepresentableAdapter -// private lateinit var bankrollReport: BankrollReport private var bankrollDetailsMenu: Menu? = null @@ -66,7 +60,7 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) - if (requestCode == REQUEST_CODE_EDIT && resultCode == RESULT_OK) { + if (requestCode == RequestCode.BANKROLL_EDIT.value && resultCode == RESULT_OK) { if (data?.getStringExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName) != null) { activity?.setResult(RESULT_OK, data) activity?.finish() @@ -217,7 +211,7 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc * Open Bankroll edit activity */ private fun editBankroll() { - EditableDataActivity.newInstanceForResult(this, LiveData.BANKROLL, this.bankrollId, REQUEST_CODE_EDIT) + EditableDataActivity.newInstanceForResult(this, LiveData.BANKROLL, this.bankrollId, RequestCode.BANKROLL_EDIT.value) } } \ No newline at end of file From d0b142dad944cfc8cd2ceac0e943c5681d973e0b Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Jun 2019 11:25:17 +0200 Subject: [PATCH 096/197] Fixes currency and such --- .../calculus/bankroll/BankrollCalculator.kt | 1 + .../calculus/bankroll/BankrollReport.kt | 5 ++ .../android/model/realm/Bankroll.kt | 9 +++ .../ui/fragment/BankrollDetailsFragment.kt | 81 +++++++++---------- .../android/ui/fragment/BankrollFragment.kt | 2 +- .../android/ui/view/RowViewType.kt | 2 +- 6 files changed, 56 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt index 3f7b144a..63507abc 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt @@ -22,6 +22,7 @@ class BankrollCalculator { val bankrolls: List = if (setup.bankrollId != null) { val bankroll = realm.findById(setup.bankrollId) ?: throw PAIllegalStateException("Bankroll not found with id=${setup.bankrollId}") + report.currency = bankroll.utilCurrency listOf(bankroll) } else realm.where(Bankroll::class.java).findAll() diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt index f3bbe059..e8a3c761 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt @@ -21,6 +21,11 @@ import kotlin.collections.HashMap */ class BankrollReport(var setup: BankrollReportSetup) { + /** + * The java.util.Currency + */ + var currency: Currency? = null + /** * The value of the bankroll */ diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt index 8f5574a2..9c1c4f08 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt @@ -14,6 +14,7 @@ import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.BankrollRow import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow +import net.pokeranalytics.android.util.UserDefaults import java.util.* open class Bankroll : RealmObject(), NameManageable, RowRepresentable { @@ -118,4 +119,12 @@ open class Bankroll : RealmObject(), NameManageable, RowRepresentable { } + val utilCurrency: java.util.Currency + get() { + this.currency?.code?.let { + return java.util.Currency.getInstance(it) + } + return UserDefaults.currency + } + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt index 533b8c7b..88e393ce 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt @@ -56,6 +56,7 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc super.onViewCreated(view, savedInstanceState) initData() initUI() + updateUI() } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -65,17 +66,17 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc activity?.setResult(RESULT_OK, data) activity?.finish() } else { - BankrollReportManager.reportForBankroll(this.bankrollId) { - updateUI(it) - } + updateUI() } } } - private fun updateUI(bankrollReport: BankrollReport) { - this.initRows(bankrollReport) - this.updateMenuUI() - this.bankrollAdapter.notifyDataSetChanged() + override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { + menu?.clear() + inflater?.inflate(R.menu.toolbar_comparison_chart, menu) // TODO R.menu.toolbar_comparison_chart? + this.bankrollDetailsMenu = menu + updateMenuUI() + super.onCreateOptionsMenu(menu, inflater) } /** @@ -87,10 +88,33 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc this.bankroll = getRealm().findById(id) ?: throw PAIllegalStateException("Bankroll not found, id=$id") } - BankrollReportManager.reportForBankroll(this.bankrollId) { - updateUI(it) + } + + /** + * Init UI + */ + private fun initUI() { + + setDisplayHomeAsUpEnabled(true) + this.updateMenuUI() + + bankrollAdapter = RowRepresentableAdapter(this, this) + + val viewManager = LinearLayoutManager(requireContext()) + + recyclerView.apply { + setHasFixedSize(true) + layoutManager = viewManager + adapter = bankrollAdapter } + } + private fun updateUI() { + this.updateMenuUI() + BankrollReportManager.reportForBankroll(this.bankrollId) { bankrollReport -> + this.initRows(bankrollReport) + this.bankrollAdapter.notifyDataSetChanged() + } } private fun initRows(bankrollReport: BankrollReport) { @@ -99,9 +123,10 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.global)) - val totalComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.total) - val netComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.netResult) - val netBankedComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.netBanked) + val currency = this.bankroll.utilCurrency + val totalComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.total, currency = currency) + val netComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.netResult, currency = currency) + val netBankedComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.netBanked, currency = currency) rows.add( CustomizableRowRepresentable( @@ -130,7 +155,7 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc bankrollReport.transactionBuckets.keys.forEach { key -> bankrollReport.transactionBuckets[key]?.let { transactionBucket -> val typeName = transactionBucket.name - val computedStat = ComputedStat(Stat.NET_RESULT, transactionBucket.total) + val computedStat = ComputedStat(Stat.NET_RESULT, transactionBucket.total, currency = currency) rows.add( CustomizableRowRepresentable( RowViewType.TITLE_VALUE, @@ -144,25 +169,6 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc } - /** - * Init UI - */ - private fun initUI() { - - setDisplayHomeAsUpEnabled(true) - this.updateMenuUI() - - bankrollAdapter = RowRepresentableAdapter(this, this) - - val viewManager = LinearLayoutManager(requireContext()) - - recyclerView.apply { - setHasFixedSize(true) - layoutManager = viewManager - adapter = bankrollAdapter - } - } - /** * Update menu UI */ @@ -175,7 +181,6 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc setToolbarTitle(this.bankroll.name) bankrollDetailsMenu?.findItem(R.id.settings)?.isVisible = true } - } // StaticRowRepresentableDataSource @@ -190,16 +195,8 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc } - override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { - menu?.clear() - inflater?.inflate(R.menu.toolbar_comparison_chart, menu) - this.bankrollDetailsMenu = menu - updateMenuUI() - super.onCreateOptionsMenu(menu, inflater) - } - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item!!.itemId) { + when (item?.itemId) { R.id.settings -> editBankroll() } return true diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt index 6cb4fb42..47cc09fc 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt @@ -101,7 +101,7 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour //TODO: Refresh bankrolls initData() } else { - dataListAdapter.notifyDataSetChanged() + initData() } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt index 9a453d39..d5044187 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt @@ -151,7 +151,7 @@ enum class RowViewType(private var layoutRes: Int) { itemView.findViewById(R.id.title)?.let { it.text = row.localizedTitle(itemView.context) } - val computedStat = ComputedStat(Stat.NET_RESULT, report.total) + val computedStat = ComputedStat(Stat.NET_RESULT, report.total, currency = report.currency) itemView.findViewById(R.id.value)?.setTextFormat(computedStat.format(), itemView.context) } From 7e267abe2770579fa92d872b1101654f23595028 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Jun 2019 11:29:30 +0200 Subject: [PATCH 097/197] Fixes transaction currency --- .../ui/adapter/FeedTransactionRowRepresentableAdapter.kt | 1 + .../net/pokeranalytics/android/ui/view/TransactionRowView.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedTransactionRowRepresentableAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedTransactionRowRepresentableAdapter.kt index ea262236..9691d7bd 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedTransactionRowRepresentableAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedTransactionRowRepresentableAdapter.kt @@ -40,6 +40,7 @@ class FeedTransactionRowRepresentableAdapter( * Display a transaction view */ inner class RowTransactionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { + fun bind(position: Int, row: Transaction?, adapter: FeedTransactionRowRepresentableAdapter) { itemView.transactionRow.setData(row as Transaction) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/TransactionRowView.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/TransactionRowView.kt index f9971876..eb9b6fa4 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/TransactionRowView.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/TransactionRowView.kt @@ -63,7 +63,7 @@ class TransactionRowView : FrameLayout { rowTransaction.transactionSubtitle.text = subtitle // Amount - val formattedStat = ComputedStat(Stat.NET_RESULT, transaction.amount).format() + val formattedStat = ComputedStat(Stat.NET_RESULT, transaction.amount, currency = transaction.bankroll?.utilCurrency).format() rowTransaction.transactionAmount.setTextFormat(formattedStat, context) } From 29b3d553400f44fc0be90ef9770f41f677e2669e Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Jun 2019 12:00:28 +0200 Subject: [PATCH 098/197] Fixes bankroll graph currencies --- .../android/calculus/bankroll/BankrollReport.kt | 13 +++++++++---- .../android/model/interfaces/Dated.kt | 7 ++++++- .../pokeranalytics/android/model/realm/Bankroll.kt | 2 +- .../pokeranalytics/android/model/realm/Currency.kt | 12 ++++++++---- .../pokeranalytics/android/model/realm/Session.kt | 6 +++--- .../android/model/realm/Transaction.kt | 6 +++--- 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt index e8a3c761..cd83fb07 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt @@ -7,11 +7,12 @@ import io.realm.Realm import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition -import net.pokeranalytics.android.model.interfaces.DatedGraphEntry +import net.pokeranalytics.android.model.interfaces.DatedBankrollGraphEntry import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Transaction import net.pokeranalytics.android.ui.graph.DataSetFactory import net.pokeranalytics.android.util.extensions.findById +import timber.log.Timber import java.util.* import kotlin.collections.HashMap @@ -122,12 +123,12 @@ class BankrollReport(var setup: BankrollReportSetup) { /** * The list of dated items used for the graph */ - private var evolutionItems: MutableList = mutableListOf() + private var evolutionItems: MutableList = mutableListOf() /** * Adds a list of dated items to the evolution items used to get the bankroll graph */ - fun addDatedItems(items: Collection) { + fun addDatedItems(items: Collection) { this.evolutionItems.addAll(items) } @@ -167,7 +168,11 @@ class BankrollReport(var setup: BankrollReportSetup) { var total = this.initial this.evolutionItems.forEach { - total += it.amount + val rate = it.bankroll?.rate ?: 1.0 + + Timber.d("rate = $rate, amount = ${it.amount}") + total += it.amount * rate + Timber.d("total = $total") val point = BRGraphPoint(total, it.date, it.objectIdentifier) this.evolutionPoints.add(point) } diff --git a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Dated.kt b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Dated.kt index bb20862a..a3d8f428 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Dated.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Dated.kt @@ -1,5 +1,6 @@ package net.pokeranalytics.android.model.interfaces +import net.pokeranalytics.android.model.realm.Bankroll import java.util.* interface Dated { @@ -14,4 +15,8 @@ interface DatedValue : Dated { } -interface DatedGraphEntry : DatedValue, GraphIdentifiableEntry \ No newline at end of file +interface DatedBankrollGraphEntry : DatedValue, GraphIdentifiableEntry { + + var bankroll: Bankroll? + +} diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt index 9c1c4f08..00af3d42 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt @@ -41,7 +41,7 @@ open class Bankroll : RealmObject(), NameManageable, RowRepresentable { val rate: Double get() { - return this.currency?.rate ?: 1.0 + return this.currency?.rate ?: Currency.DEFAULT_RATE } override fun getDisplayName(context: Context): String { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt index 304f3a2b..75655d36 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt @@ -8,8 +8,12 @@ import java.util.* open class Currency : RealmObject() { - @Ignore - val DEFAULTRATE: Double = 1.0 + companion object { + + @Ignore + val DEFAULT_RATE: Double = 1.0 + + } @PrimaryKey var id = UUID.randomUUID().toString() @@ -22,11 +26,11 @@ open class Currency : RealmObject() { /** * The rate of the currency with the main currency */ - var rate: Double? = DEFAULTRATE + var rate: Double? = DEFAULT_RATE fun refreshRelatedRatedValues() { - val rate = this.rate ?: DEFAULTRATE + val rate = this.rate ?: DEFAULT_RATE val query = this.realm.where(ComputableResult::class.java) query.`in`("session.bankroll.currency.id", arrayOf(this.id)) val cResults = query.findAll() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index aa97a132..975da7d5 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -46,7 +46,7 @@ import kotlin.collections.ArrayList typealias BB = Double open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDataSource, RowRepresentable, Timed, - TimeFilterable, Filterable, DatedGraphEntry { + TimeFilterable, Filterable, DatedBankrollGraphEntry { enum class Type { CASH_GAME, @@ -235,7 +235,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat var creationDate: Date = Date() // The bankroll hosting the results - var bankroll: Bankroll? = null + override var bankroll: Bankroll? = null set(value) { field = value this.updateRowRepresentation() @@ -399,7 +399,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat @Ignore override var amount: Double = 0.0 get() { - return this.computableResult?.ratedNet ?: 0.0 + return this.result?.net ?: 0.0 } /** diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt index 66432946..a3ef5368 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt @@ -27,7 +27,7 @@ import kotlin.collections.ArrayList open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSource, RowRepresentable, TimeFilterable, - Filterable, DatedGraphEntry { + Filterable, DatedBankrollGraphEntry { companion object { @@ -60,7 +60,7 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo override var id = UUID.randomUUID().toString() // The bankroll of the transaction - var bankroll: Bankroll? = null + override var bankroll: Bankroll? = null // The amount of the transaction override var amount: Double = 0.0 @@ -144,7 +144,7 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo } override fun formattedValue(stat: Stat): TextFormat { - return stat.format(this.amount) + return stat.format(this.amount, currency = this.bankroll?.utilCurrency) } override fun legendValues( From 3130f0232797f4f5413f4fa3f8416288606b47bb Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Jun 2019 12:16:26 +0200 Subject: [PATCH 099/197] Fixes layout of disclosure rows --- app/src/main/res/layout/row_legend_default.xml | 4 ++-- app/src/main/res/layout/row_title_value_arrow.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/row_legend_default.xml b/app/src/main/res/layout/row_legend_default.xml index caeace10..974a8900 100644 --- a/app/src/main/res/layout/row_legend_default.xml +++ b/app/src/main/res/layout/row_legend_default.xml @@ -35,7 +35,7 @@ android:layout_width="wrap_content" android:layout_height="0dp" android:layout_marginTop="8dp" - android:layout_marginEnd="16dp" + android:layout_marginEnd="8dp" app:layout_constraintEnd_toStartOf="@+id/nextArrow" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toEndOf="@+id/stat1Name" @@ -48,7 +48,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" - android:layout_marginEnd="16dp" + android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/nextArrow" diff --git a/app/src/main/res/layout/row_title_value_arrow.xml b/app/src/main/res/layout/row_title_value_arrow.xml index 52ab6295..6491c8a9 100644 --- a/app/src/main/res/layout/row_title_value_arrow.xml +++ b/app/src/main/res/layout/row_title_value_arrow.xml @@ -24,7 +24,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" + android:layout_marginEnd="8dp" android:ellipsize="end" android:gravity="end" android:maxLines="1" From e76c09cdeae0949ac631f3df3e018276df1ffdf2 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Jun 2019 12:35:23 +0200 Subject: [PATCH 100/197] Fixes test build --- .../android/unitTests/BankrollInstrumentedUnitTest.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/BankrollInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/BankrollInstrumentedUnitTest.kt index a76308ed..82807498 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/BankrollInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/BankrollInstrumentedUnitTest.kt @@ -72,12 +72,12 @@ class BankrollInstrumentedUnitTest : SessionInstrumentedUnitTest() { } val br1 = realm.where(Bankroll::class.java).equalTo("name", "br1").findFirst() - val brSetup1 = BankrollReportSetup(br1) + val brSetup1 = BankrollReportSetup(br1?.id) val report1 = BankrollCalculator.computeReport(realm, brSetup1) Assert.assertEquals(400.0, report1.total, EPSILON) val br2 = realm.where(Bankroll::class.java).equalTo("name", "br2").findFirst() - val brSetup2 = BankrollReportSetup(br2) + val brSetup2 = BankrollReportSetup(br2?.id) val report2 = BankrollCalculator.computeReport(realm, brSetup2) Assert.assertEquals(2000.0, report2.total, EPSILON) @@ -116,7 +116,7 @@ class BankrollInstrumentedUnitTest : SessionInstrumentedUnitTest() { } - val brSetup1 = BankrollReportSetup(br1) + val brSetup1 = BankrollReportSetup(br1?.id) val report1 = BankrollCalculator.computeReport(realm, brSetup1) Assert.assertEquals(400.0, report1.total, EPSILON) From 7f8e9240ed9f18106d91df79934f16b466881ecc Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Jun 2019 14:19:33 +0200 Subject: [PATCH 101/197] Removes logs --- .../android/calculus/bankroll/BankrollReport.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt index cd83fb07..69df9109 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt @@ -12,7 +12,6 @@ import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Transaction import net.pokeranalytics.android.ui.graph.DataSetFactory import net.pokeranalytics.android.util.extensions.findById -import timber.log.Timber import java.util.* import kotlin.collections.HashMap @@ -170,9 +169,9 @@ class BankrollReport(var setup: BankrollReportSetup) { this.evolutionItems.forEach { val rate = it.bankroll?.rate ?: 1.0 - Timber.d("rate = $rate, amount = ${it.amount}") +// Timber.d("rate = $rate, amount = ${it.amount}") total += it.amount * rate - Timber.d("total = $total") +// Timber.d("total = $total") val point = BRGraphPoint(total, it.date, it.objectIdentifier) this.evolutionPoints.add(point) } From 3385beced2af63eac77c331e8daf9e133c25cb16 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Jun 2019 15:13:33 +0200 Subject: [PATCH 102/197] Fixes crash on bankroll main row --- app/build.gradle | 2 +- .../android/ui/fragment/BankrollDetailsFragment.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4600a2b6..174fae59 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,7 +29,7 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 37 + versionCode 38 versionName "2.0.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt index 88e393ce..7a188e18 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt @@ -123,7 +123,7 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.global)) - val currency = this.bankroll.utilCurrency + val currency = if (this.bankrollId != null) { this.bankroll.utilCurrency } else { null } val totalComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.total, currency = currency) val netComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.netResult, currency = currency) val netBankedComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.netBanked, currency = currency) From 90fe6ef40f08c2f06800ac610726541978c0621c Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Jun 2019 18:43:17 +0200 Subject: [PATCH 103/197] CSV import update --- .../android/ui/fragment/ImportFragment.kt | 9 +- .../android/util/csv/CSVDescriptor.kt | 4 +- .../android/util/csv/CSVImporter.kt | 10 + .../android/util/csv/SessionCSVDescriptor.kt | 174 +++++++++++++++--- app/src/main/res/layout/bottom_sheet_sum.xml | 4 +- app/src/main/res/layout/fragment_import.xml | 40 ++++ app/src/main/res/values/styles.xml | 11 ++ 7 files changed, 226 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt index 0727dd0d..c0d0775c 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt @@ -12,13 +12,14 @@ import net.pokeranalytics.android.R import net.pokeranalytics.android.ui.activity.components.ResultCode import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.util.csv.CSVImporter +import net.pokeranalytics.android.util.csv.ImportDelegate import net.pokeranalytics.android.util.csv.ImportException import timber.log.Timber import java.io.InputStream import java.util.* import kotlin.coroutines.CoroutineContext -class ImportFragment : RealmFragment() { +class ImportFragment : RealmFragment(), ImportDelegate { val coroutineContext: CoroutineContext get() = Dispatchers.Main @@ -81,4 +82,10 @@ class ImportFragment : RealmFragment() { } + // ImportDelegate + + override fun parsingCountUpdate(count: Int) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt index f4ef3174..bf517d5e 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt @@ -3,6 +3,7 @@ package net.pokeranalytics.android.util.csv import io.realm.Realm import io.realm.RealmModel import org.apache.commons.csv.CSVRecord +import timber.log.Timber /** * The various sources of CSV @@ -77,9 +78,8 @@ abstract class CSVDescriptor(var source: DataSource, vararg elements: CSVField) if (index >= 0) { count++ } - } - + Timber.d("source= ${this.source.name} > total fields = ${this.fields.size}, identified = $count") return count == this.fields.size } 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 7a1bfb90..a2772236 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 @@ -11,6 +11,10 @@ import java.io.Reader class ImportException(message: String) : Exception(message) +interface ImportDelegate { + fun parsingCountUpdate(count: Int) +} + /** * A CSVImporter is a class in charge of parsing a CSV file and processing it * When starting the parsing of a file, the instance will search for a CSVDescriptor, which describes @@ -20,6 +24,11 @@ class ImportException(message: String) : Exception(message) */ open class CSVImporter(istream: InputStream) { + /** + * The object being notified of the import progress + */ + var delegate: ImportDelegate? = null + /** * Number of commits required to commit a Realm transaction */ @@ -100,6 +109,7 @@ open class CSVImporter(istream: InputStream) { val parsingIndex = index + 1 if (parsingIndex % COMMIT_FREQUENCY == 0) { Timber.d("****** committing at $parsingIndex sessions...") + this.delegate?.parsingCountUpdate(parsingIndex) realm.commitTransaction() realm.beginTransaction() } diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt index d33e719f..c70d15bb 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt @@ -1,11 +1,14 @@ package net.pokeranalytics.android.util.csv import io.realm.Realm +import io.realm.RealmModel import net.pokeranalytics.android.model.Limit import net.pokeranalytics.android.model.TableSize import net.pokeranalytics.android.model.TournamentType import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Session +import net.pokeranalytics.android.model.realm.Transaction +import net.pokeranalytics.android.model.realm.TransactionType import net.pokeranalytics.android.model.utils.SessionUtils import net.pokeranalytics.android.util.extensions.getOrCreate import net.pokeranalytics.android.util.extensions.setHourMinutes @@ -83,7 +86,22 @@ sealed class SessionField { override val numberFormat: String? = null ) : NumberCSVField - data class Blind(override var header: String, override var callback: ((String) -> Pair?)? = null) : BlindCSVField + data class Rebuy( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + data class Addon( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + + data class Blind(override var header: String, override var callback: ((String) -> Pair?)? = null) : + BlindCSVField + data class Game(override var header: String) : CSVField data class Location(override var header: String) : CSVField data class LocationType(override var header: String) : CSVField @@ -118,7 +136,8 @@ sealed class SessionField { /** * A SessionCSVDescriptor is a CSVDescriptor specialized in parsing Session objects */ -class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean, vararg elements: CSVField) : DataCSVDescriptor(source, *elements) { +class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean, vararg elements: CSVField) : + DataCSVDescriptor(source, *elements) { companion object { val pokerIncomeCash: CSVDescriptor = SessionCSVDescriptor( @@ -142,17 +161,19 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean val pokerBankrollTracker: CSVDescriptor = SessionCSVDescriptor( DataSource.POKER_BANKROLL_TRACKER, true, - SessionField.Start("starttime", dateFormat = "MM/dd/yyyy HH:mm"), - SessionField.End("endtime", dateFormat = "MM/dd/yyyy HH:mm"), + SessionField.Start("starttime", dateFormat = "MM/dd/yy HH:mm"), + SessionField.End("endtime", dateFormat = "MM/dd/yy HH:mm"), SessionField.SessionType("variant"), SessionField.Buyin("buyin"), SessionField.CashedOut("cashout"), + SessionField.Rebuy("rebuycosts"), + SessionField.Addon("addoncosts"), SessionField.Break("breakminutes"), SessionField.LimitType("limit"), SessionField.Game("game"), SessionField.Bankroll("currency"), // same as currency code - SessionField.Location("location"), - SessionField.Comment("sessionnote"), + SessionField.Location("type"), +// SessionField.Comment("sessionnote"), SessionField.Tips("expensesfromstack"), SessionField.SmallBlind("smallblind"), SessionField.BigBlind("bigblind"), @@ -209,7 +230,8 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean SessionField.LocationType("Location Type"), SessionField.Comment("Notes"), SessionField.CurrencyCode("Currency"), - SessionField.Blind("Stakes", callback = { value -> // $10/20 + SessionField.Blind("Stakes", callback = { value -> + // $10/20 value.drop(1) val blinds = value.split("/") if (blinds.size == 2) { @@ -222,10 +244,90 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean } + private enum class DataType { + TRANSACTION, + SESSION; + + companion object { + + fun valueForString(type: String): DataType? { + return when (type) { + "Deposit/Payout" -> TRANSACTION + "Cash Game", "Tournament" -> SESSION + else -> null + } + } + } + + } + /** * Parses a [record] and return an optional Session */ - override fun parseData(realm: Realm, record: CSVRecord): Session? { + override fun parseData(realm: Realm, record: CSVRecord): RealmModel? { + + var dataType: DataType? = null + val typeField = fields.firstOrNull { it is SessionField.SessionType } + typeField?.let { field -> + this.fieldMapping[field]?.let { index -> + val typeValue = record.get(index) + dataType = DataType.valueForString(typeValue) + } + } + + return when (dataType) { + DataType.TRANSACTION -> parseTransaction(realm, record) + else -> parseSession(realm, record) + } + + } + + fun parseTransaction(realm: Realm, record: CSVRecord): Transaction? { + + var date: Date? = null + var amount: Double? = null + var type: TransactionType? = null + var currencyCode: String? = null + var currencyRate: Double? = null + + fields.forEach { field -> + + val index = this.fieldMapping[field] + if (index != null) { + val value = record.get(index) + when (field) { + is SessionField.Start -> { + date = field.parse(value) + } + is SessionField.Buyin -> amount = field.parse(value) + is SessionField.SessionType -> { + type = realm.getOrCreate(value) + } + is SessionField.CurrencyCode -> currencyCode = value + is SessionField.CurrencyRate -> currencyRate = field.parse(value) + else -> { + } + } + } + } + + if (date != null && amount != null && type != null && currencyCode != null) { + + val transaction = realm.copyToRealm(Transaction()) + transaction.date = date!! + transaction.amount = amount!! + transaction.type = type + + val bankroll = Bankroll.getOrCreate(realm, currencyCode!!, currencyRate = currencyRate) + transaction.bankroll = bankroll + + return transaction + } + + return null + } + + fun parseSession(realm: Realm, record: CSVRecord): Session? { val session = Session.newInstance(realm, this.isTournament) @@ -233,6 +335,7 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean var bankrollName: String? = null var currencyCode: String? = null var currencyRate: Double? = null + var additionalBuyins = 0.0 // rebuy + addon fields.forEach { field -> @@ -246,18 +349,34 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean is SessionField.End -> { session.endDate = field.parse(value) } - is SessionField.StartTime -> { session.startDate?.setHourMinutes(value) } - is SessionField.EndTime -> { session.endDate?.setHourMinutes(value) } + is SessionField.StartTime -> { + session.startDate?.setHourMinutes(value) + } + is SessionField.EndTime -> { + session.endDate?.setHourMinutes(value) + } is SessionField.Buyin -> session.result?.buyin = field.parse(value) is SessionField.CashedOut -> session.result?.cashout = field.parse(value) + is SessionField.Addon -> additionalBuyins += field.parse(value) ?: 0.0 + is SessionField.Rebuy -> additionalBuyins += field.parse(value) ?: 0.0 is SessionField.Tips -> session.result?.tips = field.parse(value) is SessionField.Break -> { field.parse(value)?.let { session.breakDuration = it.toLong() * 60 * 1000 } } - is SessionField.Game -> session.game = realm.getOrCreate(value) - is SessionField.Location -> session.location = realm.getOrCreate(value) + is SessionField.Game -> { + if (value.isNotEmpty()) { + session.game = realm.getOrCreate(value) + } else { + } + } + is SessionField.Location -> { + if (value.isNotEmpty()) { + session.location = realm.getOrCreate(value) + } else { + } + } is SessionField.Bankroll -> bankrollName = value is SessionField.LimitType -> session.limit = Limit.getInstance(value)?.ordinal is SessionField.Comment -> session.comment = value @@ -274,31 +393,44 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean session.type = type.ordinal } } - is SessionField.TournamentPosition -> session.result?.tournamentFinalPosition = field.parse(value)?.toInt() + is SessionField.TournamentPosition -> session.result?.tournamentFinalPosition = + field.parse(value)?.toInt() is SessionField.TournamentName -> session.tournamentName = realm.getOrCreate(value) - is SessionField.TournamentType -> session.tournamentType = TournamentType.getValueForLabel(value)?.ordinal - is SessionField.TournamentNumberOfPlayers -> session.tournamentNumberOfPlayers = field.parse(value)?.toInt() + is SessionField.TournamentType -> session.tournamentType = + TournamentType.getValueForLabel(value)?.ordinal + is SessionField.TournamentNumberOfPlayers -> session.tournamentNumberOfPlayers = + field.parse(value)?.toInt() is SessionField.CurrencyCode -> currencyCode = value is SessionField.CurrencyRate -> currencyRate = field.parse(value) - else -> { } + else -> { + } } } } + if (bankrollName.isNullOrEmpty()) { + bankrollName = "Import" + } + session.bankroll = Bankroll.getOrCreate(realm, bankrollName ?: "Import", isLive, currencyCode, currencyRate) val startDate = session.startDate val endDate = session.endDate val net = session.result?.net + session.result?.buyin?.let { + session.result?.buyin = it + additionalBuyins + } - return if (startDate != null && endDate != null && net != null) { // valid session - val unique = SessionUtils.unicityCheck(realm, startDate, endDate, net) - if (unique) session else null - } else { // invalid session - null + if (startDate != null && endDate != null && net != null) { // valid session + if (SessionUtils.unicityCheck(realm, startDate, endDate, net)) { + return session + } } + session.deleteFromRealm() + return null + } } \ No newline at end of file diff --git a/app/src/main/res/layout/bottom_sheet_sum.xml b/app/src/main/res/layout/bottom_sheet_sum.xml index b5451b6a..b657682d 100644 --- a/app/src/main/res/layout/bottom_sheet_sum.xml +++ b/app/src/main/res/layout/bottom_sheet_sum.xml @@ -15,7 +15,7 @@ android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" - android:text="+ 1000 $" + tools:text="+ 1000 $" app:layout_constraintEnd_toStartOf="@+id/button2" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_chainStyle="packed" @@ -30,7 +30,7 @@ android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" - android:text="+ 2000 $" + tools:text="+ 2000 $" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/button1" diff --git a/app/src/main/res/layout/fragment_import.xml b/app/src/main/res/layout/fragment_import.xml index efbb84d7..3d2e9ce5 100644 --- a/app/src/main/res/layout/fragment_import.xml +++ b/app/src/main/res/layout/fragment_import.xml @@ -5,4 +5,44 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index eecdebee..94f1afb6 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -351,4 +351,15 @@ 28sp + + + + From 79c2152d9ec81e0fb788652aa76693b1af2fde37 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Jun 2019 18:43:26 +0200 Subject: [PATCH 104/197] Bumping version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 174fae59..5e354191 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,8 +29,8 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 38 - versionName "2.0.1" + versionCode 39 + versionName "2.0.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From 9af997c6a0d3e9fc344b41b276af10f043e25e32 Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 13 Jun 2019 18:39:23 +0200 Subject: [PATCH 105/197] CSV import update --- .../android/model/interfaces/Manageable.kt | 7 + .../android/model/realm/Filter.kt | 5 - .../android/model/realm/Session.kt | 2 + .../android/model/utils/DataUtils.kt | 39 +++ .../android/model/utils/SessionUtils.kt | 21 -- .../android/ui/fragment/FiltersFragment.kt | 6 +- .../android/ui/fragment/ImportFragment.kt | 73 ++++- .../android/util/csv/CSVDescriptor.kt | 43 ++- .../android/util/csv/CSVImporter.kt | 75 +++-- .../android/util/csv/ProductCSVDescriptors.kt | 112 ++++++++ .../android/util/csv/SessionCSVDescriptor.kt | 265 ++---------------- .../android/util/csv/SessionField.kt | 122 ++++++++ app/src/main/res/layout/fragment_import.xml | 41 ++- app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/styles.xml | 20 +- 15 files changed, 520 insertions(+), 312 deletions(-) create mode 100644 app/src/main/java/net/pokeranalytics/android/model/utils/DataUtils.kt delete mode 100644 app/src/main/java/net/pokeranalytics/android/model/utils/SessionUtils.kt create mode 100644 app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt create mode 100644 app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt diff --git a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt index 26ebd99a..aa9ea5f2 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt @@ -46,6 +46,8 @@ interface NameManageable : Manageable { } +class Identificator(var id: String, var clazz: Class) + /** * An interface associate a unique uniqueIdentifier to an object */ @@ -56,6 +58,11 @@ interface Identifiable : RealmModel { */ var id: String + val identificator: Identificator + get() { + return Identificator(this.id, this::class.java) + } + } /** diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt index 010e2340..3a506826 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt @@ -42,11 +42,6 @@ open class Filter : RealmObject(), RowRepresentable, Editable, Deletable, Counta //return realm.copyToRealm(filter) } - // Get a queryWith by its id - fun getFilterBydId(realm: Realm, filterId: String): Filter? { - return realm.where().equalTo("id", filterId).findFirst() - } - inline fun queryOn(realm: Realm, query: Query, sortField: String? = null): RealmResults { val rootQuery = realm.where() var realmQuery = query.queryWith(rootQuery) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 975da7d5..25651110 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -67,6 +67,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } companion object { + fun newInstance(realm: Realm, isTournament: Boolean, bankroll: Bankroll? = null): Session { val session = Session() session.result = Result() @@ -76,6 +77,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat session.bankroll = realm.where().findFirst() } session.type = if (isTournament) Session.Type.TOURNAMENT.ordinal else Session.Type.CASH_GAME.ordinal + return realm.copyToRealm(session) } diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/DataUtils.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/DataUtils.kt new file mode 100644 index 00000000..2e0bd3a6 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/model/utils/DataUtils.kt @@ -0,0 +1,39 @@ +package net.pokeranalytics.android.model.utils + +import io.realm.Realm +import net.pokeranalytics.android.model.realm.Session +import net.pokeranalytics.android.model.realm.Transaction +import net.pokeranalytics.android.model.realm.TransactionType +import java.util.* + +class DataUtils { + + companion object { + + /** + * Returns true if the provided parameters doesn't correspond to an existing session + */ + fun sessionCount(realm: Realm, startDate: Date, endDate: Date, net: Double): Int { + val sessions = realm.where(Session::class.java) + .equalTo("startDate", startDate) + .equalTo("endDate", endDate) + .equalTo("result.net", net) + .findAll() + return sessions.size + } + + /** + * Returns true if the provided parameters doesn't correspond to an existing transaction + */ + fun transactionUnicityCheck(realm: Realm, date: Date, amount: Double, type: TransactionType): Boolean { + val transactions = realm.where(Transaction::class.java) + .equalTo("date", date) + .equalTo("amount", amount) + .equalTo("type.id", type.id) + .findAll() + return transactions.isEmpty() + } + + } + +} diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/SessionUtils.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/SessionUtils.kt deleted file mode 100644 index d8d93f7e..00000000 --- a/app/src/main/java/net/pokeranalytics/android/model/utils/SessionUtils.kt +++ /dev/null @@ -1,21 +0,0 @@ -package net.pokeranalytics.android.model.utils - -import io.realm.Realm -import net.pokeranalytics.android.model.realm.Session -import java.util.* - -class SessionUtils { - - companion object { - - /** - * Returns true if the provided parameters doesn't correspond to an existing session - */ - fun unicityCheck(realm: Realm, startDate: Date, endDate: Date, net: Double) : Boolean { - val sessions = realm.where(Session::class.java).equalTo("startDate", startDate).equalTo("endDate", endDate).equalTo("result.net", net).findAll() - return sessions.isEmpty() - } - - } - -} diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt index 0a1b696e..564fb7ac 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt @@ -12,6 +12,7 @@ import kotlinx.android.synthetic.main.fragment_editable_data.recyclerView import kotlinx.android.synthetic.main.fragment_filters.* import kotlinx.android.synthetic.main.fragment_filters.view.toolbar import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.realm.Filter import net.pokeranalytics.android.ui.activity.FilterDetailsActivity @@ -27,6 +28,7 @@ import net.pokeranalytics.android.ui.interfaces.FilterableType import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow import net.pokeranalytics.android.util.Preferences +import net.pokeranalytics.android.util.extensions.findById import net.pokeranalytics.android.util.extensions.sorted import timber.log.Timber @@ -173,7 +175,9 @@ open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource, val realm = getRealm() primaryKey?.let { - currentFilter = realm.copyFromRealm(Filter.getFilterBydId(realm, it)) + + val filter = realm.findById(it) ?: throw PAIllegalStateException("Can't find filter with id=$it") + currentFilter = realm.copyFromRealm(filter) isUpdating = true } ?: run { currentFilter = Filter.newInstance(this.filterableType.uniqueIdentifier) //realm.copyFromRealm(Filter.newInstanceForResult(realm, this.filterableType.ordinal)) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt index c0d0775c..e8025a10 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt @@ -4,18 +4,19 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import kotlinx.android.synthetic.main.fragment_import.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.async import kotlinx.coroutines.launch import net.pokeranalytics.android.R -import net.pokeranalytics.android.ui.activity.components.ResultCode import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.util.csv.CSVImporter import net.pokeranalytics.android.util.csv.ImportDelegate import net.pokeranalytics.android.util.csv.ImportException import timber.log.Timber import java.io.InputStream +import java.text.NumberFormat import java.util.* import kotlin.coroutines.CoroutineContext @@ -26,6 +27,7 @@ class ImportFragment : RealmFragment(), ImportDelegate { private lateinit var filePath: String private lateinit var inputStream: InputStream + private lateinit var importer: CSVImporter fun setData(path: String) { this.filePath = path @@ -43,12 +45,34 @@ class ImportFragment : RealmFragment(), ImportDelegate { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + this.initUI() + this.startImport() } - fun startImport() { + private fun initUI() { + + this.imported.text = requireContext().getString(R.string.imported) + this.total.text = requireContext().getString(R.string.total) + + this.save.isEnabled = false + this.save.setOnClickListener { + this.end() + } - var shouldDismissActivity = false + this.cancel.setOnClickListener { + this.cancel() + this.end() + } + + } + + private fun startImport() { + +// var shouldDismissActivity = false + + this.importer = CSVImporter(inputStream) + this.importer.delegate = this GlobalScope.launch(coroutineContext) { @@ -57,10 +81,9 @@ class ImportFragment : RealmFragment(), ImportDelegate { Timber.d(">>> Start Import...") try { - val csv = CSVImporter(inputStream) - csv.start() + importer.start() } catch (e: ImportException) { - shouldDismissActivity = true +// shouldDismissActivity = true } val e = Date() val duration = (e.time - s.time) / 1000.0 @@ -69,23 +92,43 @@ class ImportFragment : RealmFragment(), ImportDelegate { } test.await() - if (shouldDismissActivity) { +// if (shouldDismissActivity) { +// +// activity?.let { +// it.setResult(ResultCode.IMPORT_UNRECOGNIZED_FORMAT.value) +// it.finish() +// } +// +// } else { +// } + importDidFinish() - activity?.let { - it.setResult(ResultCode.IMPORT_UNRECOGNIZED_FORMAT.value) - it.finish() - } + } - } + } - } + private fun cancel() { + this.importer.cancel(getRealm()) + } + + private fun importDidFinish() { + this.save.isEnabled = true + + } + + private fun end() { + activity?.finish() } + val numberFormatter = NumberFormat.getNumberInstance() + // ImportDelegate - override fun parsingCountUpdate(count: Int) { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + override fun parsingCountUpdate(importedCount: Int, totalCount: Int) { + this.counter.text = this.numberFormatter.format(importedCount) + this.totalCounter.text = this.numberFormatter.format(totalCount) } + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt index bf517d5e..847a775c 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt @@ -1,7 +1,10 @@ package net.pokeranalytics.android.util.csv import io.realm.Realm -import io.realm.RealmModel +import io.realm.kotlin.deleteFromRealm +import net.pokeranalytics.android.model.interfaces.Identifiable +import net.pokeranalytics.android.model.interfaces.Identificator +import net.pokeranalytics.android.util.extensions.findById import org.apache.commons.csv.CSVRecord import timber.log.Timber @@ -17,19 +20,30 @@ enum class DataSource { /** * A DataCSVDescriptor produces RealmModel instances for each row */ -abstract class DataCSVDescriptor(source: DataSource, vararg elements: CSVField) : CSVDescriptor(source, *elements) { +abstract class DataCSVDescriptor(source: DataSource, vararg elements: CSVField) : CSVDescriptor(source, *elements) { - val realmModels = mutableListOf() + /** + * List of Realm object identificators + */ + val realmModelIds = mutableListOf() abstract fun parseData(realm: Realm, record: CSVRecord): T? - override fun parse(realm: Realm, record: CSVRecord) { + override fun parse(realm: Realm, record: CSVRecord): Int { val data = this.parseData(realm, record) data?.let { - this.realmModels.add(it) + this.realmModelIds.add(it.identificator) } + return if (data != null) 1 else 0 + } + override fun cancel(realm: Realm) { + realm.executeTransaction { + this.realmModelIds.forEach { identificator -> + realm.findById(identificator.clazz, identificator.id)?.deleteFromRealm() + } + } } } @@ -59,7 +73,19 @@ abstract class CSVDescriptor(var source: DataSource, vararg elements: CSVField) * The list of all managed CSVDescriptors */ val all: List = - listOf(SessionCSVDescriptor.pokerIncomeCash, SessionCSVDescriptor.pokerBankrollTracker, SessionCSVDescriptor.runGoodCashGames, SessionCSVDescriptor.runGoodTournaments) + listOf(ProductCSVDescriptors.pokerIncomeCash, + ProductCSVDescriptors.pokerBankrollTracker, + ProductCSVDescriptors.runGoodCashGames, + ProductCSVDescriptors.runGoodTournaments) + } + + /** + * Method called when iterating on a CSVRecord + */ + abstract fun parse(realm: Realm, record: CSVRecord): Int + + open fun cancel(realm: Realm) { + } /** @@ -83,9 +109,4 @@ abstract class CSVDescriptor(var source: DataSource, vararg elements: CSVField) return count == this.fields.size } - /** - * Method called when iterating on a CSVRecord - */ - abstract fun parse(realm: Realm, record: CSVRecord) - } 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 a2772236..17476360 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 @@ -1,7 +1,10 @@ package net.pokeranalytics.android.util.csv +import android.os.Handler +import android.os.Looper import io.realm.Realm import org.apache.commons.csv.CSVFormat +import org.apache.commons.csv.CSVParser import org.apache.commons.csv.CSVRecord import timber.log.Timber import java.io.FileReader @@ -12,7 +15,7 @@ import java.io.Reader class ImportException(message: String) : Exception(message) interface ImportDelegate { - fun parsingCountUpdate(count: Int) + fun parsingCountUpdate(importedCount: Int, totalCount: Int) } /** @@ -60,11 +63,27 @@ open class CSVImporter(istream: InputStream) { * Stores the descriptors found */ private var usedDescriptors: MutableList = mutableListOf() + /** * The currently used CSVDescriptor for parsing */ private var currentDescriptor: CSVDescriptor? = null + /** + * The number of valid record parsed + */ + private var totalParsedRecords = 0 + + /** + * The number of successfully imported records + */ + private var importedRecords = 0 + + /** + * The CSV parser + */ + private lateinit var parser: CSVParser + /** * Constructs a CSVParser object and starts parsing the CSV */ @@ -80,7 +99,7 @@ open class CSVImporter(istream: InputStream) { reader = InputStreamReader(this.inputStream) } - val parser = CSVFormat.DEFAULT.withAllowMissingColumnNames().parse(reader) + this.parser = CSVFormat.DEFAULT.withAllowMissingColumnNames().parse(reader) Timber.d("Starting import...") @@ -89,6 +108,7 @@ open class CSVImporter(istream: InputStream) { parser.forEachIndexed { index, record -> Timber.d("line $index") + this.notifyDelegate() if (this.currentDescriptor == null) { // find descriptor this.currentDescriptor = this.findDescriptor(record) @@ -106,10 +126,10 @@ open class CSVImporter(istream: InputStream) { } else { // parse + // batch commit val parsingIndex = index + 1 if (parsingIndex % COMMIT_FREQUENCY == 0) { Timber.d("****** committing at $parsingIndex sessions...") - this.delegate?.parsingCountUpdate(parsingIndex) realm.commitTransaction() realm.beginTransaction() } @@ -117,19 +137,27 @@ open class CSVImporter(istream: InputStream) { this.currentDescriptor?.let { if (record.size() == 0) { this.usedDescriptors.add(it) - this.currentDescriptor = null // reset descriptor when encountering an empty line (multiple descriptors can be found in a single file) + this.currentDescriptor = + null // reset descriptor when encountering an empty line (multiple descriptors can be found in a single file) this.descriptorFindingAttempts = 0 } else { - it.parse(realm, record) + val count = it.parse(realm, record) + + this.importedRecords += count + this.totalParsedRecords++ + + this.notifyDelegate() } } ?: run { realm.cancelTransaction() - throw IllegalStateException("CSVDescriptor should never be null here") + throw ImportException("CSVDescriptor should never be null here") } } } + this.notifyDelegate() + realm.commitTransaction() Timber.d("Ending import...") @@ -137,10 +165,16 @@ open class CSVImporter(istream: InputStream) { realm.close() } + private fun notifyDelegate() { + Handler(Looper.getMainLooper()).post { + this.delegate?.parsingCountUpdate(this.importedRecords, this.totalParsedRecords) + } + } + /** * Search for a descriptor in the list of managed formats */ - private fun findDescriptor(record: CSVRecord) : CSVDescriptor? { + private fun findDescriptor(record: CSVRecord): CSVDescriptor? { CSVDescriptor.all.forEach { descriptor -> if (descriptor.matches(record)) { @@ -152,17 +186,26 @@ open class CSVImporter(istream: InputStream) { return null } - fun save(realm: Realm) { - +// fun save(realm: Realm) { +// +// this.usedDescriptors.forEach { descriptor -> +// +// if (descriptor is DataCSVDescriptor<*>) { +// realm.executeTransaction { +// realm.copyToRealm(descriptor.realmModels) +// } +// } +// } +// } + + fun cancel(realm: Realm) { + this.parser.close() + realm.refresh() + + this.currentDescriptor?.cancel(realm) this.usedDescriptors.forEach { descriptor -> - - if (descriptor is DataCSVDescriptor<*>) { - realm.executeTransaction { - realm.copyToRealm(descriptor.realmModels) - } - } + descriptor.cancel(realm) } - } } diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt new file mode 100644 index 00000000..a475972b --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt @@ -0,0 +1,112 @@ +package net.pokeranalytics.android.util.csv + +class ProductCSVDescriptors { + + companion object { + + val pokerIncomeCash: CSVDescriptor = SessionCSVDescriptor( + DataSource.POKER_INCOME, + false, + SessionField.Start("Start Time"), + SessionField.End("End Time"), + SessionField.Buyin("Buy In"), + SessionField.CashedOut("Cashed Out"), + SessionField.Break("Break Minutes"), + SessionField.LimitType("Limit Type"), + SessionField.Game("Game"), + SessionField.Bankroll("Bankroll"), + SessionField.Location("Location"), + SessionField.Location("Location Type"), + SessionField.Comment("Note"), + SessionField.Tips("Tips"), + SessionField.Blind("Stake") + ) + + val pokerBankrollTracker: CSVDescriptor = SessionCSVDescriptor( + DataSource.POKER_BANKROLL_TRACKER, + true, + SessionField.Start("starttime", dateFormat = "MM/dd/yy HH:mm"), + SessionField.End("endtime", dateFormat = "MM/dd/yy HH:mm"), + SessionField.SessionType("variant"), + SessionField.Buyin("buyin"), + SessionField.CashedOut("cashout"), + SessionField.Rebuy("rebuycosts"), + SessionField.Addon("addoncosts"), + SessionField.Break("breakminutes"), + SessionField.LimitType("limit"), + SessionField.Game("game"), + SessionField.Bankroll("currency"), // same as currency code + SessionField.Location("type"), +// SessionField.Comment("sessionnote"), + SessionField.Tips("expensesfromstack"), + SessionField.SmallBlind("smallblind"), + SessionField.BigBlind("bigblind"), + SessionField.TournamentNumberOfPlayers("player"), + SessionField.TournamentPosition("place"), + SessionField.TournamentName("mttname"), + SessionField.CurrencyCode("currency"), + SessionField.CurrencyRate("exchangerate"), + SessionField.TableSize("tablesize") + ) + + val runGoodTournaments: CSVDescriptor = SessionCSVDescriptor( + DataSource.RUNGOOD, + true, + SessionField.Start("Start Date", dateFormat = "dd/MM/yyyy"), + SessionField.StartTime("Start Time"), + SessionField.End("End Date"), + SessionField.EndTime("End Time"), + SessionField.Buyin("Total Buy-In"), + SessionField.CashedOut("Winnings"), + SessionField.NetResult("Profit"), + SessionField.Break("Break"), + SessionField.LimitType("Limit Type"), + SessionField.Game("Game"), + SessionField.Bankroll("Bankroll"), + SessionField.TableSize("Table Type"), + SessionField.Location("Location"), + SessionField.LocationType("Location Type"), + SessionField.Comment("Notes"), + SessionField.CurrencyCode("Currency"), + SessionField.TournamentName("Event Name"), + SessionField.TournamentNumberOfPlayers("Total Players"), + SessionField.TournamentPosition("Finished Place"), + SessionField.TournamentType("Single-Table/Multi-Table") + + ) + + val runGoodCashGames: CSVDescriptor = SessionCSVDescriptor( + DataSource.RUNGOOD, + false, + SessionField.Start("Start Date", dateFormat = "dd/MM/yyyy"), + SessionField.StartTime("Start Time", dateFormat = "HH:mm"), + SessionField.End("End Date", dateFormat = "dd/MM/yyyy"), + SessionField.EndTime("End Time", dateFormat = "HH:mm"), + SessionField.Buyin("Total Buy-In"), + SessionField.CashedOut("Cashed Out"), + SessionField.NetResult("Profit"), + SessionField.Break("Break"), + SessionField.LimitType("Limit Type"), + SessionField.Game("Game"), + SessionField.Bankroll("Bankroll"), + SessionField.TableSize("Table Type"), + SessionField.Location("Location"), + SessionField.LocationType("Location Type"), + SessionField.Comment("Notes"), + SessionField.CurrencyCode("Currency"), + SessionField.Blind("Stakes", callback = { value -> + // $10/20 + value.drop(1) + val blinds = value.split("/") + if (blinds.size == 2) { + return@Blind Pair(blinds.first().toDouble(), blinds.last().toDouble()) + } else { + return@Blind null + } + }) + ) + + + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt index c70d15bb..54dda264 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt @@ -1,248 +1,26 @@ package net.pokeranalytics.android.util.csv import io.realm.Realm -import io.realm.RealmModel import net.pokeranalytics.android.model.Limit import net.pokeranalytics.android.model.TableSize import net.pokeranalytics.android.model.TournamentType +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Transaction import net.pokeranalytics.android.model.realm.TransactionType -import net.pokeranalytics.android.model.utils.SessionUtils +import net.pokeranalytics.android.model.utils.DataUtils import net.pokeranalytics.android.util.extensions.getOrCreate import net.pokeranalytics.android.util.extensions.setHourMinutes import org.apache.commons.csv.CSVRecord +import timber.log.Timber import java.util.* -/** - * The enumeration of Session fields - */ -sealed class SessionField { - - data class Start( - override var header: String, - override var callback: ((String) -> Date?)? = null, - override val dateFormat: String? = null - ) : DateCSVField - - data class StartTime( - override var header: String, - override var callback: ((String) -> Date?)? = null, - override val dateFormat: String? = null - ) : DateCSVField - - data class End( - override var header: String, - override var callback: ((String) -> Date?)? = null, - override val dateFormat: String? = null - ) : DateCSVField - - data class EndTime( - override var header: String, - override var callback: ((String) -> Date?)? = null, - override val dateFormat: String? = null - ) : DateCSVField - - data class Buyin( - override var header: String, - override var callback: ((String) -> Double?)? = null, - override val numberFormat: String? = null - ) : NumberCSVField - - data class NetResult( - override var header: String, - override var callback: ((String) -> Double?)? = null, - override val numberFormat: String? = null - ) : NumberCSVField - - data class CashedOut( - override var header: String, - override var callback: ((String) -> Double?)? = null, - override val numberFormat: String? = null - ) : NumberCSVField - - data class Break( - override var header: String, - override var callback: ((String) -> Double?)? = null, - override val numberFormat: String? = null - ) : NumberCSVField - - data class Tips( - override var header: String, - override var callback: ((String) -> Double?)? = null, - override val numberFormat: String? = null - ) : NumberCSVField - - data class SmallBlind( - override var header: String, - override var callback: ((String) -> Double?)? = null, - override val numberFormat: String? = null - ) : NumberCSVField - - data class BigBlind( - override var header: String, - override var callback: ((String) -> Double?)? = null, - override val numberFormat: String? = null - ) : NumberCSVField - - data class Rebuy( - override var header: String, - override var callback: ((String) -> Double?)? = null, - override val numberFormat: String? = null - ) : NumberCSVField - - data class Addon( - override var header: String, - override var callback: ((String) -> Double?)? = null, - override val numberFormat: String? = null - ) : NumberCSVField - - - data class Blind(override var header: String, override var callback: ((String) -> Pair?)? = null) : - BlindCSVField - - data class Game(override var header: String) : CSVField - data class Location(override var header: String) : CSVField - data class LocationType(override var header: String) : CSVField - data class Bankroll(override var header: String) : CSVField - data class LimitType(override var header: String) : CSVField - data class Comment(override var header: String) : CSVField - data class SessionType(override var header: String) : CSVField - data class TableSize(override var header: String) : CSVField - data class CurrencyCode(override var header: String) : CSVField - data class TournamentName(override var header: String) : CSVField - data class TournamentType(override var header: String) : CSVField - - data class CurrencyRate( - override var header: String, - override var callback: ((String) -> Double?)? = null, - override val numberFormat: String? = null - ) : NumberCSVField - - data class TournamentPosition( - override var header: String, - override var callback: ((String) -> Double?)? = null, - override val numberFormat: String? = null - ) : NumberCSVField - - data class TournamentNumberOfPlayers( - override var header: String, - override var callback: ((String) -> Double?)? = null, - override val numberFormat: String? = null - ) : NumberCSVField -} - /** * A SessionCSVDescriptor is a CSVDescriptor specialized in parsing Session objects */ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean, vararg elements: CSVField) : - DataCSVDescriptor(source, *elements) { - - companion object { - val pokerIncomeCash: CSVDescriptor = SessionCSVDescriptor( - DataSource.POKER_INCOME, - false, - SessionField.Start("Start Time"), - SessionField.End("End Time"), - SessionField.Buyin("Buy In"), - SessionField.CashedOut("Cashed Out"), - SessionField.Break("Break Minutes"), - SessionField.LimitType("Limit Type"), - SessionField.Game("Game"), - SessionField.Bankroll("Bankroll"), - SessionField.Location("Location"), - SessionField.Location("Location Type"), - SessionField.Comment("Note"), - SessionField.Tips("Tips"), - SessionField.Blind("Stake") - ) - - val pokerBankrollTracker: CSVDescriptor = SessionCSVDescriptor( - DataSource.POKER_BANKROLL_TRACKER, - true, - SessionField.Start("starttime", dateFormat = "MM/dd/yy HH:mm"), - SessionField.End("endtime", dateFormat = "MM/dd/yy HH:mm"), - SessionField.SessionType("variant"), - SessionField.Buyin("buyin"), - SessionField.CashedOut("cashout"), - SessionField.Rebuy("rebuycosts"), - SessionField.Addon("addoncosts"), - SessionField.Break("breakminutes"), - SessionField.LimitType("limit"), - SessionField.Game("game"), - SessionField.Bankroll("currency"), // same as currency code - SessionField.Location("type"), -// SessionField.Comment("sessionnote"), - SessionField.Tips("expensesfromstack"), - SessionField.SmallBlind("smallblind"), - SessionField.BigBlind("bigblind"), - SessionField.TournamentNumberOfPlayers("player"), - SessionField.TournamentPosition("place"), - SessionField.TournamentName("mttname"), - SessionField.CurrencyCode("currency"), - SessionField.CurrencyRate("exchangerate"), - SessionField.TableSize("tablesize") - ) - - val runGoodTournaments: CSVDescriptor = SessionCSVDescriptor( - DataSource.RUNGOOD, - true, - SessionField.Start("Start Date", dateFormat = "dd/MM/yyyy"), - SessionField.StartTime("Start Time"), - SessionField.End("End Date"), - SessionField.EndTime("End Time"), - SessionField.Buyin("Total Buy-In"), - SessionField.CashedOut("Winnings"), - SessionField.NetResult("Profit"), - SessionField.Break("Break"), - SessionField.LimitType("Limit Type"), - SessionField.Game("Game"), - SessionField.Bankroll("Bankroll"), - SessionField.TableSize("Table Type"), - SessionField.Location("Location"), - SessionField.LocationType("Location Type"), - SessionField.Comment("Notes"), - SessionField.CurrencyCode("Currency"), - SessionField.TournamentName("Event Name"), - SessionField.TournamentNumberOfPlayers("Total Players"), - SessionField.TournamentPosition("Finished Place"), - SessionField.TournamentType("Single-Table/Multi-Table") - - ) - - val runGoodCashGames: CSVDescriptor = SessionCSVDescriptor( - DataSource.RUNGOOD, - false, - SessionField.Start("Start Date", dateFormat = "dd/MM/yyyy"), - SessionField.StartTime("Start Time", dateFormat = "HH:mm"), - SessionField.End("End Date", dateFormat = "dd/MM/yyyy"), - SessionField.EndTime("End Time", dateFormat = "HH:mm"), - SessionField.Buyin("Total Buy-In"), - SessionField.CashedOut("Cashed Out"), - SessionField.NetResult("Profit"), - SessionField.Break("Break"), - SessionField.LimitType("Limit Type"), - SessionField.Game("Game"), - SessionField.Bankroll("Bankroll"), - SessionField.TableSize("Table Type"), - SessionField.Location("Location"), - SessionField.LocationType("Location Type"), - SessionField.Comment("Notes"), - SessionField.CurrencyCode("Currency"), - SessionField.Blind("Stakes", callback = { value -> - // $10/20 - value.drop(1) - val blinds = value.split("/") - if (blinds.size == 2) { - return@Blind Pair(blinds.first().toDouble(), blinds.last().toDouble()) - } else { - return@Blind null - } - }) - ) - - } + DataCSVDescriptor(source, *elements) { private enum class DataType { TRANSACTION, @@ -264,7 +42,7 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean /** * Parses a [record] and return an optional Session */ - override fun parseData(realm: Realm, record: CSVRecord): RealmModel? { + override fun parseData(realm: Realm, record: CSVRecord): Identifiable? { var dataType: DataType? = null val typeField = fields.firstOrNull { it is SessionField.SessionType } @@ -282,7 +60,7 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean } - fun parseTransaction(realm: Realm, record: CSVRecord): Transaction? { + private fun parseTransaction(realm: Realm, record: CSVRecord): Transaction? { var date: Date? = null var amount: Double? = null @@ -313,24 +91,32 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean if (date != null && amount != null && type != null && currencyCode != null) { - val transaction = realm.copyToRealm(Transaction()) - transaction.date = date!! - transaction.amount = amount!! - transaction.type = type + if (DataUtils.transactionUnicityCheck(realm, date!!, amount!!, type!!)) { - val bankroll = Bankroll.getOrCreate(realm, currencyCode!!, currencyRate = currencyRate) - transaction.bankroll = bankroll + val transaction = realm.copyToRealm(Transaction()) + transaction.date = date!! + transaction.amount = amount!! + transaction.type = type - return transaction + val bankroll = Bankroll.getOrCreate(realm, currencyCode!!, currencyRate = currencyRate) + transaction.bankroll = bankroll + return transaction + } else { + Timber.d("Transaction already exists") + } + } else { + Timber.d("Can't import transaction: date=$date, amount=$amount, type=${type?.name}") } return null } - fun parseSession(realm: Realm, record: CSVRecord): Session? { + private fun parseSession(realm: Realm, record: CSVRecord): Session? { val session = Session.newInstance(realm, this.isTournament) + + var isLive = true var bankrollName: String? = null var currencyCode: String? = null @@ -423,14 +209,17 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean } if (startDate != null && endDate != null && net != null) { // valid session - if (SessionUtils.unicityCheck(realm, startDate, endDate, net)) { + if (DataUtils.sessionCount(realm, startDate, endDate, net) == 1) { // session already in realm, we'd love not put it in Realm before doing the check return session + } else { + Timber.d("Session already exists") } + } else { + Timber.d("Can't import session: sd=$startDate, ed=$endDate, net=$net") } session.deleteFromRealm() return null - } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt new file mode 100644 index 00000000..6f0876af --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt @@ -0,0 +1,122 @@ +package net.pokeranalytics.android.util.csv + +import java.util.* + + +/** + * The enumeration of Session fields + */ +sealed class SessionField { + + data class Start( + override var header: String, + override var callback: ((String) -> Date?)? = null, + override val dateFormat: String? = null + ) : DateCSVField + + data class StartTime( + override var header: String, + override var callback: ((String) -> Date?)? = null, + override val dateFormat: String? = null + ) : DateCSVField + + data class End( + override var header: String, + override var callback: ((String) -> Date?)? = null, + override val dateFormat: String? = null + ) : DateCSVField + + data class EndTime( + override var header: String, + override var callback: ((String) -> Date?)? = null, + override val dateFormat: String? = null + ) : DateCSVField + + data class Buyin( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + data class NetResult( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + data class CashedOut( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + data class Break( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + data class Tips( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + data class SmallBlind( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + data class BigBlind( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + data class Rebuy( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + data class Addon( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + + data class Blind(override var header: String, override var callback: ((String) -> Pair?)? = null) : + BlindCSVField + + data class Game(override var header: String) : CSVField + data class Location(override var header: String) : CSVField + data class LocationType(override var header: String) : CSVField + data class Bankroll(override var header: String) : CSVField + data class LimitType(override var header: String) : CSVField + data class Comment(override var header: String) : CSVField + data class SessionType(override var header: String) : CSVField + data class TableSize(override var header: String) : CSVField + data class CurrencyCode(override var header: String) : CSVField + data class TournamentName(override var header: String) : CSVField + data class TournamentType(override var header: String) : CSVField + + data class CurrencyRate( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + data class TournamentPosition( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + data class TournamentNumberOfPlayers( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField +} diff --git a/app/src/main/res/layout/fragment_import.xml b/app/src/main/res/layout/fragment_import.xml index 3d2e9ce5..67018bcd 100644 --- a/app/src/main/res/layout/fragment_import.xml +++ b/app/src/main/res/layout/fragment_import.xml @@ -5,9 +5,21 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + + + + - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2e0726ec..d9c9355e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -37,6 +37,7 @@ The filter cannot be deleted because it is currently selected. Custom field The item is used in one or more transactions…Please delete the linked transactions first + Imported Address Naming suggestions diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 94f1afb6..23e128e8 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -353,7 +353,16 @@ - + + + + From 136d1a55a7335e6072247f58a183b27889720080 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 14 Jun 2019 12:14:16 +0200 Subject: [PATCH 106/197] Fixing import issues --- app/src/main/AndroidManifest.xml | 14 ++-- .../android/model/interfaces/Manageable.kt | 13 ++-- .../android/model/interfaces/Timed.kt | 7 +- .../android/model/realm/Bankroll.kt | 5 ++ .../android/model/realm/CustomField.kt | 4 ++ .../android/model/realm/CustomFieldEntry.kt | 4 ++ .../android/model/realm/Filter.kt | 9 +-- .../android/model/realm/Game.kt | 5 ++ .../android/model/realm/Location.kt | 5 ++ .../android/model/realm/ReportSetup.kt | 4 ++ .../android/model/realm/Session.kt | 11 ++- .../android/model/realm/SessionSet.kt | 11 ++- .../android/model/realm/TournamentFeature.kt | 5 ++ .../android/model/realm/TournamentName.kt | 5 ++ .../android/model/realm/Transaction.kt | 5 +- .../android/model/realm/TransactionType.kt | 5 ++ .../android/ui/activity/HomeActivity.kt | 26 +++---- .../android/ui/activity/ImportActivity.kt | 71 +++++++++++++++---- .../android/ui/fragment/GraphFragment.kt | 14 ++-- .../android/ui/graph/GraphUnderlyingEntry.kt | 6 +- .../CustomizableRowRepresentable.kt | 5 +- .../android/util/csv/CSVDescriptor.kt | 29 ++++++-- .../android/util/csv/CSVImporter.kt | 22 +++--- .../android/util/csv/SessionCSVDescriptor.kt | 6 +- 24 files changed, 197 insertions(+), 94 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b9ef5ab9..b7e5f47c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -32,6 +32,13 @@ + + + + @@ -45,13 +52,6 @@ - - - - ) +class ObjectIdentifier(var id: String, var clazz: Class) /** * An interface associate a unique uniqueIdentifier to an object @@ -58,11 +57,15 @@ interface Identifiable : RealmModel { */ var id: String - val identificator: Identificator + /** + * required because "this.class" returns the proxy class, making where queries crash + */ + val realmObjectClass: Class + + val objectIdentifier: ObjectIdentifier get() { - return Identificator(this.id, this::class.java) + return ObjectIdentifier(this.id, this.realmObjectClass) } - } /** diff --git a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt index 31ca5fe9..4b4c752f 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt @@ -1,14 +1,9 @@ package net.pokeranalytics.android.model.interfaces import net.pokeranalytics.android.ui.graph.GraphUnderlyingEntry -import net.pokeranalytics.android.ui.graph.ObjectIdentifier import java.util.* -interface GraphIdentifiableEntry : GraphUnderlyingEntry, Identifiable { - - val objectIdentifier : ObjectIdentifier - -} +interface GraphIdentifiableEntry : GraphUnderlyingEntry, Identifiable interface Timed : GraphIdentifiableEntry { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt index 00af3d42..3a5910ef 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt @@ -4,11 +4,13 @@ import android.content.Context import io.realm.Realm import io.realm.RealmObject import io.realm.RealmResults +import io.realm.annotations.Ignore import io.realm.annotations.LinkingObjects import io.realm.annotations.PrimaryKey import io.realm.kotlin.where import net.pokeranalytics.android.R import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.ui.view.RowRepresentable @@ -127,4 +129,7 @@ open class Bankroll : RealmObject(), NameManageable, RowRepresentable { return UserDefaults.currency } + @Ignore + override val realmObjectClass: Class = Bankroll::class.java + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt index 2b03ba11..98266561 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt @@ -11,6 +11,7 @@ import io.realm.kotlin.where import net.pokeranalytics.android.R import net.pokeranalytics.android.model.Criteria import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource @@ -28,6 +29,9 @@ import kotlin.collections.ArrayList open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDataSource, RowRepresentable { + @Ignore + override val realmObjectClass: Class = CustomField::class.java + /** * The custom field type: a list of items, a number or an amont */ diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt index f4716084..9a98cfc1 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt @@ -12,6 +12,7 @@ import io.realm.kotlin.where import net.pokeranalytics.android.R import net.pokeranalytics.android.exceptions.ModelException import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType @@ -27,6 +28,9 @@ import java.util.Currency open class CustomFieldEntry : RealmObject(), NameManageable, RowRepresentable { + @Ignore + override val realmObjectClass: Class = CustomFieldEntry::class.java + @PrimaryKey override var id = UUID.randomUUID().toString() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt index 3a506826..25059c97 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt @@ -5,16 +5,14 @@ import io.realm.Realm import io.realm.RealmList import io.realm.RealmObject import io.realm.RealmResults +import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey import io.realm.kotlin.where import net.pokeranalytics.android.R import net.pokeranalytics.android.model.filter.Filterable import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition -import net.pokeranalytics.android.model.interfaces.CountableUsage -import net.pokeranalytics.android.model.interfaces.Deletable -import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus -import net.pokeranalytics.android.model.interfaces.Editable +import net.pokeranalytics.android.model.interfaces.* import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType import net.pokeranalytics.android.ui.interfaces.FilterableType import net.pokeranalytics.android.ui.view.ImageDecorator @@ -32,6 +30,9 @@ import java.util.* */ open class Filter : RealmObject(), RowRepresentable, Editable, Deletable, CountableUsage, ImageDecorator { + @Ignore + override val realmObjectClass: Class = Filter::class.java + companion object { // Create a new instance diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt index 2334baa0..9ee4dcc6 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt @@ -3,10 +3,12 @@ package net.pokeranalytics.android.model.realm import android.content.Context import io.realm.Realm import io.realm.RealmObject +import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey import io.realm.kotlin.where import net.pokeranalytics.android.R import net.pokeranalytics.android.model.interfaces.CountableUsage +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource @@ -20,6 +22,9 @@ import kotlin.collections.ArrayList open class Game : RealmObject(), NameManageable, StaticRowRepresentableDataSource, RowRepresentable, CountableUsage { + @Ignore + override val realmObjectClass: Class = Game::class.java + companion object { val rowRepresentation : List by lazy { val rows = ArrayList() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt index df4136e4..9f64f7fb 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt @@ -4,9 +4,11 @@ import android.content.Context import com.google.android.libraries.places.api.model.Place import io.realm.Realm import io.realm.RealmObject +import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey import io.realm.kotlin.where import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.ui.view.RowRepresentable @@ -16,6 +18,9 @@ import java.util.* open class Location : RealmObject(), NameManageable, RowRepresentable { + @Ignore + override val realmObjectClass: Class = Location::class.java + @PrimaryKey override var id = UUID.randomUUID().toString() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/ReportSetup.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/ReportSetup.kt index 2db6f02e..f813dd75 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/ReportSetup.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/ReportSetup.kt @@ -11,6 +11,7 @@ import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.model.Criteria import net.pokeranalytics.android.model.interfaces.Deletable import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.util.extensions.findById @@ -19,6 +20,9 @@ import java.util.* open class ReportSetup : RealmObject(), RowRepresentable, Deletable { + @Ignore + override val realmObjectClass: Class = ReportSetup::class.java + @PrimaryKey override var id = UUID.randomUUID().toString() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 25651110..99e5ed52 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -16,6 +16,7 @@ import net.pokeranalytics.android.calculus.ComputedStat import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.StatFormattingException import net.pokeranalytics.android.exceptions.ModelException +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.Limit import net.pokeranalytics.android.model.TableSize import net.pokeranalytics.android.model.TournamentType @@ -29,7 +30,6 @@ import net.pokeranalytics.android.model.utils.SessionSetManager import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.UnmanagedRowRepresentableException import net.pokeranalytics.android.ui.fragment.GraphFragment -import net.pokeranalytics.android.ui.graph.ObjectIdentifier import net.pokeranalytics.android.ui.view.* import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRow @@ -422,7 +422,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat this.computableResults?.forEachIndexed { index, computableResult -> computableResult.updateWith(this) if (index > 0) { - throw IllegalStateException("Session cannot have more than one computable result") + throw PAIllegalStateException("Session cannot have more than one computable result") } } this.sessionSet?.computeStats() @@ -1149,10 +1149,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } - // Timed - - override val objectIdentifier: ObjectIdentifier - get() = ObjectIdentifier(this.id, Session::class.java) - + @Ignore + override val realmObjectClass: Class = Session::class.java } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt index da9976b6..c447de69 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt @@ -4,16 +4,17 @@ import android.content.Context import io.realm.Realm import io.realm.RealmObject import io.realm.RealmResults +import io.realm.annotations.Ignore import io.realm.annotations.LinkingObjects import io.realm.annotations.PrimaryKey import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.StatFormattingException -import net.pokeranalytics.android.util.TextFormat import net.pokeranalytics.android.model.filter.Filterable import net.pokeranalytics.android.model.filter.QueryCondition +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.Timed -import net.pokeranalytics.android.ui.graph.ObjectIdentifier import net.pokeranalytics.android.util.NULL_TEXT +import net.pokeranalytics.android.util.TextFormat import java.text.DateFormat import java.util.* @@ -138,10 +139,8 @@ open class SessionSet() : RealmObject(), Timed, Filterable { } } - // Timed - - override val objectIdentifier: ObjectIdentifier - get() = ObjectIdentifier(this.id, SessionSet::class.java) + @Ignore + override val realmObjectClass: Class = SessionSet::class.java } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/TournamentFeature.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/TournamentFeature.kt index f11f0e73..5a51c448 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/TournamentFeature.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/TournamentFeature.kt @@ -3,10 +3,12 @@ package net.pokeranalytics.android.model.realm import android.content.Context import io.realm.Realm import io.realm.RealmObject +import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey import io.realm.kotlin.where import net.pokeranalytics.android.R import net.pokeranalytics.android.model.interfaces.CountableUsage +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource @@ -30,6 +32,9 @@ open class TournamentFeature : RealmObject(), NameManageable, StaticRowRepresent } } + @Ignore + override val realmObjectClass: Class = TournamentFeature::class.java + @PrimaryKey override var id = UUID.randomUUID().toString() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/TournamentName.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/TournamentName.kt index cad45445..dadbfa2f 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/TournamentName.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/TournamentName.kt @@ -3,9 +3,11 @@ package net.pokeranalytics.android.model.realm import android.content.Context import io.realm.Realm import io.realm.RealmObject +import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey import io.realm.kotlin.where import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource @@ -28,6 +30,9 @@ open class TournamentName : RealmObject(), NameManageable, StaticRowRepresentabl } } + @Ignore + override val realmObjectClass: Class = TournamentName::class.java + @PrimaryKey override var id = UUID.randomUUID().toString() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt index a3ef5368..bbf95d07 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt @@ -13,7 +13,6 @@ import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.interfaces.* import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.fragment.GraphFragment -import net.pokeranalytics.android.ui.graph.ObjectIdentifier import net.pokeranalytics.android.ui.view.DefaultLegendValues import net.pokeranalytics.android.ui.view.LegendContent import net.pokeranalytics.android.ui.view.RowRepresentable @@ -136,8 +135,8 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo // GraphIdentifiableEntry - override val objectIdentifier: ObjectIdentifier - get() = ObjectIdentifier(this.id, Transaction::class.java) + @Ignore + override val realmObjectClass: Class = Transaction::class.java override fun entryTitle(context: Context): String { return DateFormat.getDateInstance(DateFormat.SHORT).format(this.date) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt index 6c038aa3..92edb9bd 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt @@ -3,9 +3,11 @@ package net.pokeranalytics.android.model.realm import android.content.Context import io.realm.Realm import io.realm.RealmObject +import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey import net.pokeranalytics.android.R import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.view.Localizable @@ -52,6 +54,9 @@ open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentab } + @Ignore + override val realmObjectClass: Class = TransactionType::class.java + @PrimaryKey override var id = UUID.randomUUID().toString() diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt index e9a540db..5edbd95b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt @@ -11,6 +11,7 @@ import io.realm.RealmResults import kotlinx.android.synthetic.main.activity_home.* import net.pokeranalytics.android.BuildConfig import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.realm.Currency import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.RequestCode @@ -83,6 +84,7 @@ class HomeActivity : PokerAnalyticsActivity() { override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) + setIntent(intent) intent?.let { when (intent.action) { @@ -91,11 +93,11 @@ class HomeActivity : PokerAnalyticsActivity() { if (data != null) { this.requestImportConfirmation(data) } else { - throw IllegalStateException("URI null on import") + throw PAIllegalStateException("URI null on import") } } else -> { - Timber.d("Intent ${intent.action} unmanaged") + Timber.w("Intent ${intent.action} unmanaged") } } } @@ -114,6 +116,16 @@ class HomeActivity : PokerAnalyticsActivity() { } } + // Import + + private fun requestImportConfirmation(uri: Uri) { + + showAlertDialog(context = this, title = R.string.import_confirmation, showCancelButton = true, positiveAction = { + ImportActivity.newInstanceForResult(this, uri) + }) + + } + private fun observeRealmObjects() { val realm = getRealm() @@ -164,14 +176,4 @@ class HomeActivity : PokerAnalyticsActivity() { viewPager.setCurrentItem(index, false) } - // Import - - private fun requestImportConfirmation(uri: Uri) { - - showAlertDialog(context = this, title = R.string.import_confirmation, showCancelButton = true, positiveAction = { - ImportActivity.newInstanceForResult(this, uri) - }) - - } - } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt index fd9fef8c..44427c9d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt @@ -9,6 +9,8 @@ import io.realm.Realm import net.pokeranalytics.android.R import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.RequestCode +import net.pokeranalytics.android.ui.activity.components.ResultCode +import net.pokeranalytics.android.ui.extensions.showAlertDialog import net.pokeranalytics.android.ui.fragment.ImportFragment import timber.log.Timber @@ -39,11 +41,15 @@ class ImportActivity : PokerAnalyticsActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - this.fileURI = intent.getParcelableExtra(ImportActivity.IntentKey.URI.keyName) + Timber.d("//////// data = ${intent?.data}") - setContentView(R.layout.activity_import) - initUI() + intent?.data?.let { + this.fileURI = it + } + setContentView(R.layout.activity_import) +// initUI() + requestImportConfirmation() } override fun onStop() { @@ -51,7 +57,7 @@ class ImportActivity : PokerAnalyticsActivity() { // Updates the main thread instance with newly inserted data val realm = Realm.getDefaultInstance() - realm.refresh() +// realm.refresh() realm.close() } @@ -71,16 +77,57 @@ class ImportActivity : PokerAnalyticsActivity() { } -// private fun requestPermission() { -// if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) { -// ActivityCompat.requestPermissions( -// this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), PERMISSION_REQUEST_ACCESS_FINE_LOCATION -// ) +// override fun onNewIntent(intent: Intent?) { +// super.onNewIntent(intent) +// +// Timber.d("++++++ data = ${intent?.data}") +// +// setIntent(intent) +// intent?.let { +// +// when (intent.action) { +// "android.intent.action.VIEW" -> { // import +// val data = it.data +// if (data != null) { +// this.requestImportConfirmation(data) +// } else { +// throw PAIllegalStateException("URI null on import") +// } +// } +// else -> { +// Timber.w("Intent ${intent.action} unmanaged") +// } +// } // } -// } // -// override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { -// super.onRequestPermissionsResult(requestCode, permissions, grantResults) // } + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + + when (requestCode) { + RequestCode.IMPORT.value -> { + if (resultCode == ResultCode.IMPORT_UNRECOGNIZED_FORMAT.value) { + showAlertDialog(context = this, message = R.string.unknown_import_format_popup_message, positiveAction = { + finish() + }) + } + } + } + } + + // Import + + private fun requestImportConfirmation() { + + showAlertDialog(context = this, title = R.string.import_confirmation, showCancelButton = true, positiveAction = { + initUI() +// newInstanceForResult(this, uri) + }, negativeAction = { + finish() + }) + + } + + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt index 9570c9cb..18b926a4 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt @@ -14,13 +14,14 @@ import com.github.mikephil.charting.listener.OnChartValueSelectedListener import kotlinx.android.synthetic.main.fragment_graph.* import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.Stat +import net.pokeranalytics.android.model.interfaces.ObjectIdentifier import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.ui.graph.AxisFormatting import net.pokeranalytics.android.ui.graph.GraphUnderlyingEntry -import net.pokeranalytics.android.ui.graph.ObjectIdentifier import net.pokeranalytics.android.ui.graph.setStyle import net.pokeranalytics.android.ui.view.LegendView import net.pokeranalytics.android.ui.view.MultiLineLegendView +import timber.log.Timber class GraphFragment : RealmFragment(), OnChartValueSelectedListener { @@ -183,16 +184,21 @@ class GraphFragment : RealmFragment(), OnChartValueSelectedListener { val identifier = entry.data as ObjectIdentifier getRealm().where(identifier.clazz).equalTo("id", identifier.id).findAll().firstOrNull() } - is GraphUnderlyingEntry -> entry.data as GraphUnderlyingEntry? + is GraphUnderlyingEntry -> entry.data else -> null } - statEntry?.let { + if (statEntry is GraphUnderlyingEntry) { + val groupName = dataSet?.label ?: "" val color = dataSet?.color - val legendValue = it.legendValues(stat, entry, this.style, groupName, requireContext()) + val legendValue = statEntry.legendValues(stat, entry, this.style, groupName, requireContext()) this.legendView.setItemData(legendValue, color) + + } else { + Timber.w("Data $statEntry should implement GraphUnderlyingEntry") } + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/graph/GraphUnderlyingEntry.kt b/app/src/main/java/net/pokeranalytics/android/ui/graph/GraphUnderlyingEntry.kt index 01d9ead9..e1b0a5a7 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/graph/GraphUnderlyingEntry.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/graph/GraphUnderlyingEntry.kt @@ -3,16 +3,12 @@ package net.pokeranalytics.android.ui.graph import android.content.Context import com.github.mikephil.charting.data.Entry import net.pokeranalytics.android.calculus.Stat -import net.pokeranalytics.android.model.interfaces.GraphIdentifiableEntry +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.ui.fragment.GraphFragment import net.pokeranalytics.android.ui.view.DefaultLegendValues import net.pokeranalytics.android.ui.view.LegendContent import net.pokeranalytics.android.util.TextFormat -class ObjectIdentifier(var id: String, var clazz: Class) { - -} - interface GraphUnderlyingEntry { fun entryTitle(context: Context): String diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/CustomizableRowRepresentable.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/CustomizableRowRepresentable.kt index 84d223f6..47255dde 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/CustomizableRowRepresentable.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/CustomizableRowRepresentable.kt @@ -2,7 +2,6 @@ package net.pokeranalytics.android.ui.view.rowrepresentable import android.content.Context import net.pokeranalytics.android.calculus.ComputedStat -import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.ui.fragment.BankrollRowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType @@ -27,7 +26,7 @@ class CustomizableRowRepresentable( var value: String? = null, var computedStat: ComputedStat? = null, var isSelectable: Boolean? = false - ) : RowRepresentable, Identifiable { + ) : RowRepresentable { override fun localizedTitle(context: Context): String { @@ -42,5 +41,5 @@ class CustomizableRowRepresentable( override val viewType: Int = customViewType?.ordinal ?: RowViewType.HEADER_TITLE.ordinal - override var id: String = "" +// override var id: String = "" } diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt index 847a775c..b462c377 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt @@ -3,7 +3,8 @@ package net.pokeranalytics.android.util.csv import io.realm.Realm import io.realm.kotlin.deleteFromRealm import net.pokeranalytics.android.model.interfaces.Identifiable -import net.pokeranalytics.android.model.interfaces.Identificator +import net.pokeranalytics.android.model.interfaces.ObjectIdentifier +import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.util.extensions.findById import org.apache.commons.csv.CSVRecord import timber.log.Timber @@ -25,7 +26,7 @@ abstract class DataCSVDescriptor(source: DataSource, vararg el /** * List of Realm object identificators */ - val realmModelIds = mutableListOf() + val realmModelIds = mutableListOf() abstract fun parseData(realm: Realm, record: CSVRecord): T? @@ -33,19 +34,33 @@ abstract class DataCSVDescriptor(source: DataSource, vararg el val data = this.parseData(realm, record) data?.let { - this.realmModelIds.add(it.identificator) + Timber.d(">>>>>>> identifier added: ${it.id}") + this.realmModelIds.add(it.objectIdentifier) } return if (data != null) 1 else 0 } override fun cancel(realm: Realm) { + + Timber.d(">>>>>>> Start delete of ${realmModelIds.size}") + realm.executeTransaction { - this.realmModelIds.forEach { identificator -> - realm.findById(identificator.clazz, identificator.id)?.deleteFromRealm() + this.realmModelIds.forEach { identifier -> + val data = realm.findById(identifier.clazz, identifier.id) + if (data is Session) { + data.cleanup() + } + data?.deleteFromRealm() } + this.realmModelIds.clear() } } + override fun save(realm: Realm) { + super.save(realm) + this.realmModelIds.clear() + } + } /** @@ -84,6 +99,10 @@ abstract class CSVDescriptor(var source: DataSource, vararg elements: CSVField) */ abstract fun parse(realm: Realm, record: CSVRecord): Int + open fun save(realm: Realm) { + + } + open fun cancel(realm: Realm) { } 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 17476360..24d36530 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 @@ -186,21 +186,19 @@ open class CSVImporter(istream: InputStream) { return null } -// fun save(realm: Realm) { -// -// this.usedDescriptors.forEach { descriptor -> -// -// if (descriptor is DataCSVDescriptor<*>) { -// realm.executeTransaction { -// realm.copyToRealm(descriptor.realmModels) -// } -// } -// } -// } + fun save(realm: Realm) { + this.parser.close() +// realm.refresh() + + this.currentDescriptor?.save(realm) + this.usedDescriptors.forEach { descriptor -> + descriptor.save(realm) + } + } 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/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt index 54dda264..dda5c860 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt @@ -115,8 +115,6 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean val session = Session.newInstance(realm, this.isTournament) - - var isLive = true var bankrollName: String? = null var currencyCode: String? = null @@ -209,7 +207,8 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean } if (startDate != null && endDate != null && net != null) { // valid session - if (DataUtils.sessionCount(realm, startDate, endDate, net) == 1) { // session already in realm, we'd love not put it in Realm before doing the check + // session already in realm, we'd love not put it in Realm before doing the check + if (DataUtils.sessionCount(realm, startDate, endDate, net) == 1) { return session } else { Timber.d("Session already exists") @@ -218,6 +217,7 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean Timber.d("Can't import session: sd=$startDate, ed=$endDate, net=$net") } + session.cleanup() session.deleteFromRealm() return null } From 6bcdece0571ef2a6b1595cb60ce546362c9e2dc0 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 14 Jun 2019 12:26:36 +0200 Subject: [PATCH 107/197] Fixes refresh issue --- .../android/calculus/bankroll/BankrollReportManager.kt | 1 + .../net/pokeranalytics/android/ui/activity/ImportActivity.kt | 5 ++--- .../net/pokeranalytics/android/ui/fragment/ImportFragment.kt | 1 - .../pokeranalytics/android/util/csv/SessionCSVDescriptor.kt | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReportManager.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReportManager.kt index a6fd8917..2bb69dfb 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReportManager.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReportManager.kt @@ -27,6 +27,7 @@ object BankrollReportManager { init { val realm = Realm.getDefaultInstance() + realm.isAutoRefresh = true computableResults = realm.where(ComputableResult::class.java).findAll() bankrolls = realm.where(Bankroll::class.java).findAll() transactions = realm.where(Transaction::class.java).findAll() diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt index 44427c9d..215b21b1 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt @@ -5,7 +5,6 @@ import android.content.Intent import android.net.Uri import android.os.Bundle import androidx.fragment.app.FragmentActivity -import io.realm.Realm import net.pokeranalytics.android.R import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.RequestCode @@ -56,9 +55,9 @@ class ImportActivity : PokerAnalyticsActivity() { super.onStop() // Updates the main thread instance with newly inserted data - val realm = Realm.getDefaultInstance() +// val realm = Realm.getDefaultInstance() // realm.refresh() - realm.close() +// realm.close() } private fun initUI() { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt index e8025a10..7232cc85 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt @@ -130,5 +130,4 @@ class ImportFragment : RealmFragment(), ImportDelegate { this.totalCounter.text = this.numberFormatter.format(totalCount) } - } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt index dda5c860..fe6e26ed 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt @@ -98,7 +98,7 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean transaction.amount = amount!! transaction.type = type - val bankroll = Bankroll.getOrCreate(realm, currencyCode!!, currencyRate = currencyRate) + val bankroll = Bankroll.getOrCreate(realm, currencyCode!!, currencyCode = currencyCode!!, currencyRate = currencyRate) transaction.bankroll = bankroll return transaction } else { From 44d48bdc1006fe044586082d243dfc481894b2ad Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 14 Jun 2019 12:34:24 +0200 Subject: [PATCH 108/197] Change use of IllegalStateException to PAIllegalStateException --- .../net/pokeranalytics/android/calculus/Calculator.kt | 5 +++-- .../java/net/pokeranalytics/android/calculus/Report.kt | 3 ++- .../main/java/net/pokeranalytics/android/calculus/Stat.kt | 3 ++- .../android/calculus/bankroll/BankrollReport.kt | 2 +- .../java/net/pokeranalytics/android/model/Criteria.kt | 3 ++- .../java/net/pokeranalytics/android/model/realm/Result.kt | 5 +++-- .../net/pokeranalytics/android/model/realm/Session.kt | 8 ++++---- .../pokeranalytics/android/model/realm/TransactionType.kt | 3 ++- .../android/model/utils/SessionSetManager.kt | 5 +++-- .../android/ui/adapter/RowRepresentableDataSource.kt | 7 ++++--- .../android/ui/fragment/DataListFragment.kt | 3 ++- .../pokeranalytics/android/ui/fragment/SessionFragment.kt | 3 ++- .../android/ui/fragment/SubscriptionFragment.kt | 3 ++- .../ui/fragment/components/DeletableItemFragment.kt | 3 ++- .../components/bottomsheet/BottomSheetFragment.kt | 3 ++- .../components/bottomsheet/BottomSheetListFragment.kt | 5 +++-- .../android/ui/fragment/report/AbstractReportFragment.kt | 3 ++- 17 files changed, 41 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt index 2f1726cb..7185f0d9 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt @@ -4,6 +4,7 @@ import android.content.Context import io.realm.Realm import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.Stat.* +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.Criteria import net.pokeranalytics.android.model.combined import net.pokeranalytics.android.model.extensions.hourlyDuration @@ -95,7 +96,7 @@ class Calculator { TABLE -> TableReportActivity::class.java PROGRESS -> ProgressReportActivity::class.java COMPARISON -> ComparisonReportActivity::class.java - else -> throw IllegalStateException("undefined activity for report display") + else -> throw PAIllegalStateException("undefined activity for report display") // MAP -> R.string.map // POLYNOMIAL -> null @@ -378,7 +379,7 @@ class Calculator { } val session = - computable.session ?: throw IllegalStateException("Computing lone ComputableResult") + computable.session ?: throw PAIllegalStateException("Computing lone ComputableResult") results.addEvolutionValue(tSum, stat = NET_RESULT, data = session) results.addEvolutionValue(tSum / index, stat = AVERAGE, data = session) results.addEvolutionValue(index.toDouble(), stat = NUMBER_OF_GAMES, data = session) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt index 63501b46..03698369 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt @@ -5,6 +5,7 @@ import com.github.mikephil.charting.data.* import io.realm.Realm import io.realm.RealmResults import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.interfaces.GraphIdentifiableEntry @@ -440,7 +441,7 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu this.computedStat(stat)?.let { return it.format() } ?: run { - throw IllegalStateException("Missing stat in results") + throw PAIllegalStateException("Missing stat in results") } } diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt index ec9e50a7..ba6b27d7 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt @@ -3,6 +3,7 @@ package net.pokeranalytics.android.calculus import android.content.Context import net.pokeranalytics.android.R import net.pokeranalytics.android.exceptions.FormattingException +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.util.NULL_TEXT @@ -127,7 +128,7 @@ enum class Stat(override var uniqueIdentifier: Int) : IntIdentifiable, RowRepres MAXIMUM_DURATION -> R.string.longest_session DAYS_PLAYED -> R.string.days_played TOTAL_BUYIN -> R.string.total_buyin - else -> throw IllegalStateException("Stat ${this.name} name required but undefined") + else -> throw PAIllegalStateException("Stat ${this.name} name required but undefined") } } diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt index 69df9109..ce66fe36 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt @@ -215,7 +215,7 @@ class BankrollReportSetup(val bankrollId: String? = null, val from: Date? = null val query = Query() this.bankrollId?.let { - val bankroll = realm.findById(it) ?: throw IllegalStateException("Bankroll not found with id $it") + val bankroll = realm.findById(it) ?: throw PAIllegalStateException("Bankroll not found with id $it") val bankrollCondition = QueryCondition.AnyBankroll(bankroll) query.add(bankrollCondition) } diff --git a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt index fa679d19..67e6f1da 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt @@ -4,6 +4,7 @@ import io.realm.Realm import io.realm.Sort import io.realm.kotlin.where import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.exceptions.PokerAnalyticsException import net.pokeranalytics.android.model.Criteria.Bankrolls.comparison import net.pokeranalytics.android.model.Criteria.Blinds.comparison @@ -329,7 +330,7 @@ interface CustomFieldCriteria { var customFieldId: String fun customField(realm: Realm) : CustomField { - return realm.findById(this.customFieldId) ?: throw IllegalStateException("Custom field not found") + return realm.findById(this.customFieldId) ?: throw PAIllegalStateException("Custom field not found") } fun customFieldType(realm: Realm): Int { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt index 644d0de3..19394fcd 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt @@ -6,6 +6,7 @@ import io.realm.RealmResults import io.realm.annotations.Ignore import io.realm.annotations.LinkingObjects import io.realm.annotations.RealmClass +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.filter.Filterable import net.pokeranalytics.android.model.filter.QueryCondition @@ -52,10 +53,10 @@ open class Result : RealmObject(), Filterable { this.session?.bankroll?.let { bankroll -> if (bankroll.live) { - throw IllegalStateException("Can't set net result on a live bankroll") + throw PAIllegalStateException("Can't set net result on a live bankroll") } } ?: run { - throw IllegalStateException("Session doesn't have any bankroll") + throw PAIllegalStateException("Session doesn't have any bankroll") } field = value diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 99e5ed52..af897af9 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -500,12 +500,12 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat if (pauseDate != null) { this.breakDuration += Date().time - pauseDate.time } else { - throw IllegalStateException("When resuming, the pause date must be set") + throw PAIllegalStateException("When resuming, the pause date must be set") } this.pauseDate = null } else -> { - throw IllegalStateException("unmanaged session state") + throw PAIllegalStateException("unmanaged session state") } } } @@ -526,7 +526,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat SessionState.STARTED -> { this.pauseDate = Date() } - else -> throw IllegalStateException("Pausing a session in an unmanaged state") + else -> throw PAIllegalStateException("Pausing a session in an unmanaged state") } } } @@ -1100,7 +1100,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } } ?: run { - throw java.lang.IllegalStateException("Asking for statIds on Session without Result") + throw PAIllegalStateException("Asking for statIds on Session without Result") } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt index 92edb9bd..b6c7d4e3 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt @@ -6,6 +6,7 @@ import io.realm.RealmObject import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.NameManageable @@ -49,7 +50,7 @@ open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentab type?.let { return it } - throw IllegalStateException("Transaction type ${value.name} should exist in database!") + throw PAIllegalStateException("Transaction type ${value.name} should exist in database!") } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt index 76cce72c..8efe64ff 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt @@ -3,6 +3,7 @@ package net.pokeranalytics.android.model.utils import io.realm.RealmQuery import io.realm.RealmResults import net.pokeranalytics.android.exceptions.ModelException +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.SessionSet import kotlin.math.max @@ -23,7 +24,7 @@ class SessionSetManager { fun updateTimeline(session: Session) { if (!session.realm.isInTransaction) { - throw IllegalStateException("realm should be in transaction at this point") + throw PAIllegalStateException("realm should be in transaction at this point") } if (session.startDate == null) { @@ -154,7 +155,7 @@ class SessionSetManager { fun removeFromTimeline(session: Session) { if (!session.realm.isInTransaction) { - throw IllegalStateException("realm should be in transaction at this point") + throw PAIllegalStateException("realm should be in transaction at this point") } val sessionSet = session.sessionSet diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt index 26dec55a..51021a62 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt @@ -1,6 +1,7 @@ package net.pokeranalytics.android.ui.adapter import android.content.Context +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.util.TextFormat @@ -42,21 +43,21 @@ interface StaticRowRepresentableDataSource: RowRepresentableDataSource { this.adapterRows()?.let { return it[position] } - throw IllegalStateException("Need to implement Data Source") + throw PAIllegalStateException("Need to implement Data Source") } override fun numberOfRows(): Int { this.adapterRows()?.let { return it.size } - throw IllegalStateException("Need to implement Data Source") + throw PAIllegalStateException("Need to implement Data Source") } override fun viewTypeForPosition(position:Int): Int { this.rowRepresentableForPosition(position)?.let { return it.viewType } - throw IllegalStateException("Need to implement Data Source") + throw PAIllegalStateException("Need to implement Data Source") } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt index 67186d9d..13c4a9fc 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt @@ -13,6 +13,7 @@ import io.realm.Realm import io.realm.RealmResults import kotlinx.android.synthetic.main.fragment_data_list.* import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.interfaces.Deletable import net.pokeranalytics.android.model.interfaces.Identifiable @@ -86,7 +87,7 @@ open class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataS val itemId = item.id deleteItem(dataListAdapter, items, itemId) } else { - throw IllegalStateException("Item with position $position not found") + throw PAIllegalStateException("Item with position $position not found") } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt index 0f1a2da3..335aa4f4 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt @@ -11,6 +11,7 @@ import androidx.recyclerview.widget.DiffUtil import kotlinx.android.synthetic.main.fragment_session.* import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.extensions.SessionState import net.pokeranalytics.android.model.extensions.getState @@ -173,7 +174,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate { sessionHasBeenCustomized = true try { currentSession.updateValue(value, row) - } catch (e: IllegalStateException) { + } catch (e: PAIllegalStateException) { Toast.makeText(context, e.message, Toast.LENGTH_LONG).show() return } 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 3f26b19d..a5b20860 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 @@ -24,6 +24,7 @@ import com.android.billingclient.api.SkuDetails import com.android.billingclient.api.SkuDetailsResponseListener import kotlinx.android.synthetic.main.fragment_subscription.* import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.ui.extensions.px import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment import net.pokeranalytics.android.ui.fragment.components.ScreenSlidePageFragment @@ -101,7 +102,7 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene this.selectedProduct?.let { AppGuard.initiatePurchase(this.requireActivity(), it, this) } ?: run { - throw IllegalStateException("Attempt to initiate purchase while no product has been chosen") + throw PAIllegalStateException("Attempt to initiate purchase while no product has been chosen") } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt index 07595c6d..9136dac1 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt @@ -13,6 +13,7 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.interfaces.Deletable import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter @@ -126,7 +127,7 @@ abstract class DeletableItemFragment : RealmFragment() { } snackBar?.show() } ?: run { - throw IllegalStateException("mainLayout is not defined") + throw PAIllegalStateException("mainLayout is not defined") } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt index 8657df58..0d437430 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt @@ -15,6 +15,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment import io.realm.RealmModel import kotlinx.android.synthetic.main.fragment_bottom_sheet.* import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.ui.activity.EditableDataActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity @@ -132,7 +133,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() { SessionRow.TOURNAMENT_NAME -> LiveData.TOURNAMENT_NAME SessionRow.TOURNAMENT_FEATURE -> LiveData.TOURNAMENT_FEATURE TransactionRow.TYPE -> LiveData.TRANSACTION_TYPE - else -> throw IllegalStateException("row $row does not have an associated LiveData value") + else -> throw PAIllegalStateException("row $row does not have an associated LiveData value") } EditableDataActivity.newInstanceForResult( diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListFragment.kt index eeece10e..fa5997f7 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListFragment.kt @@ -8,6 +8,7 @@ import io.realm.RealmResults import kotlinx.android.synthetic.main.bottom_sheet_list.* import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.* import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.exceptions.RowRepresentableEditDescriptorException import net.pokeranalytics.android.ui.adapter.LiveRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter @@ -39,14 +40,14 @@ open class BottomSheetListFragment : BottomSheetFragment(), LiveRowRepresentable realmData?.let { return it[position] as RowRepresentable } - throw IllegalStateException("Need to implement Data Source") + throw PAIllegalStateException("Need to implement Data Source") } override fun numberOfRows(): Int { realmData?.let { return it.size } - throw IllegalStateException("Need to implement Data Source") + throw PAIllegalStateException("Need to implement Data Source") } override fun viewTypeForPosition(position: Int): Int { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/AbstractReportFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/AbstractReportFragment.kt index 3addaa19..fa900fa2 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/AbstractReportFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/AbstractReportFragment.kt @@ -9,6 +9,7 @@ import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat import kotlinx.android.synthetic.main.fragment_progress_report.* import net.pokeranalytics.android.calculus.Report +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.CustomFieldCriteria import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.realm.ReportSetup @@ -91,7 +92,7 @@ abstract class AbstractReportFragment : DataManagerFragment() { dialog.show() - } ?: throw IllegalStateException("Activity cannot be null") + } ?: throw PAIllegalStateException("Activity cannot be null") } From 84ab42c35ca0d9c0a65035a7e410f3b932309db8 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 14 Jun 2019 17:21:30 +0200 Subject: [PATCH 109/197] Updating import for PBT --- .../android/model/realm/Session.kt | 8 +- .../android/util/csv/CSVDescriptor.kt | 4 +- .../android/util/csv/CSVField.kt | 14 +++- .../android/util/csv/SessionCSVDescriptor.kt | 84 ++++++++++++------- .../android/util/csv/SessionField.kt | 8 ++ 5 files changed, 82 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index af897af9..293c8fc7 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -68,7 +68,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat companion object { - fun newInstance(realm: Realm, isTournament: Boolean, bankroll: Bankroll? = null): Session { + fun newInstance(realm: Realm, isTournament: Boolean, bankroll: Bankroll? = null, managed: Boolean = false): Session { val session = Session() session.result = Result() if (bankroll != null) { @@ -78,7 +78,11 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } session.type = if (isTournament) Session.Type.TOURNAMENT.ordinal else Session.Type.CASH_GAME.ordinal - return realm.copyToRealm(session) + return if (managed) { + realm.copyToRealm(session) + } else { + session + } } fun fieldNameForQueryType(queryCondition: Class < out QueryCondition >): String? { diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt index b462c377..36df0fac 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt @@ -34,7 +34,7 @@ abstract class DataCSVDescriptor(source: DataSource, vararg el val data = this.parseData(realm, record) data?.let { - Timber.d(">>>>>>> identifier added: ${it.id}") +// Timber.d(">>>>>>> identifier added: ${it.id}") this.realmModelIds.add(it.objectIdentifier) } return if (data != null) 1 else 0 @@ -42,7 +42,7 @@ abstract class DataCSVDescriptor(source: DataSource, vararg el override fun cancel(realm: Realm) { - Timber.d(">>>>>>> Start delete of ${realmModelIds.size}") +// Timber.d(">>>>>>> Start delete of ${realmModelIds.size}") realm.executeTransaction { this.realmModelIds.forEach { identifier -> diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVField.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVField.kt index 3e7e6659..1202443a 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVField.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVField.kt @@ -31,6 +31,18 @@ interface NumberCSVField: TypedCSVField { } } +interface DataCSVField : TypedCSVField { + + override fun parse(value: String): T? { + + this.callback?.let { + return it(value) + } + return null + } + +} + interface DateCSVField : TypedCSVField { val dateFormat: String? @@ -58,8 +70,8 @@ interface BlindCSVField : TypedCSVField> { val strBlinds = value.split("/") if (strBlinds.size == 2) { - val bb = strBlinds.last().toDouble() val sb = strBlinds.first().toDouble() + val bb = strBlinds.last().toDouble() return Pair(sb, bb) } else { Timber.d("Blinds could not be parsed: $value") diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt index fe6e26ed..3fc15506 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt @@ -63,11 +63,14 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean private fun parseTransaction(realm: Realm, record: CSVRecord): Transaction? { var date: Date? = null - var amount: Double? = null var type: TransactionType? = null var currencyCode: String? = null var currencyRate: Double? = null + // Poker Bankroll Tracker specifics + var buyin: Double? = null + var cashedOut: Double? = null + fields.forEach { field -> val index = this.fieldMapping[field] @@ -77,10 +80,8 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean is SessionField.Start -> { date = field.parse(value) } - is SessionField.Buyin -> amount = field.parse(value) - is SessionField.SessionType -> { - type = realm.getOrCreate(value) - } + is SessionField.Buyin -> buyin = field.parse(value) + is SessionField.CashedOut -> cashedOut = field.parse(value) is SessionField.CurrencyCode -> currencyCode = value is SessionField.CurrencyRate -> currencyRate = field.parse(value) else -> { @@ -89,13 +90,23 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean } } + val amount = if (buyin != null && buyin!! > 0) { + type = TransactionType.getByValue(TransactionType.Value.DEPOSIT, realm) + buyin + } else if (cashedOut != null && cashedOut!! > 0) { + type = TransactionType.getByValue(TransactionType.Value.WITHDRAWAL, realm) + cashedOut!! * -1 + } else { + null + } + if (date != null && amount != null && type != null && currencyCode != null) { - if (DataUtils.transactionUnicityCheck(realm, date!!, amount!!, type!!)) { + if (DataUtils.transactionUnicityCheck(realm, date!!, amount, type)) { val transaction = realm.copyToRealm(Transaction()) transaction.date = date!! - transaction.amount = amount!! + transaction.amount = amount transaction.type = type val bankroll = Bankroll.getOrCreate(realm, currencyCode!!, currencyCode = currencyCode!!, currencyRate = currencyRate) @@ -113,7 +124,10 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean private fun parseSession(realm: Realm, record: CSVRecord): Session? { - val session = Session.newInstance(realm, this.isTournament) + val session = Session.newInstance(realm, this.isTournament, managed = false) + + var startDate: Date? = null + var endDate: Date? = null var isLive = true var bankrollName: String? = null @@ -128,19 +142,30 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean val value = record.get(index) when (field) { is SessionField.Start -> { - session.startDate = field.parse(value) + startDate = field.parse(value) } is SessionField.End -> { - session.endDate = field.parse(value) + endDate = field.parse(value) } is SessionField.StartTime -> { - session.startDate?.setHourMinutes(value) + startDate?.setHourMinutes(value) } is SessionField.EndTime -> { - session.endDate?.setHourMinutes(value) + endDate?.setHourMinutes(value) + } + is SessionField.Buyin -> { + val buyin = field.parse(value) + session.result?.buyin = buyin + if (session.type == Session.Type.TOURNAMENT.ordinal) { + session.tournamentEntryFee = buyin + } else {} } - is SessionField.Buyin -> session.result?.buyin = field.parse(value) is SessionField.CashedOut -> session.result?.cashout = field.parse(value) + is SessionField.SessionType -> { + Session.Type.getValueFromString(value)?.let { type -> + session.type = type.ordinal + } + } is SessionField.Addon -> additionalBuyins += field.parse(value) ?: 0.0 is SessionField.Rebuy -> additionalBuyins += field.parse(value) ?: 0.0 is SessionField.Tips -> session.result?.tips = field.parse(value) @@ -152,14 +177,12 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean is SessionField.Game -> { if (value.isNotEmpty()) { session.game = realm.getOrCreate(value) - } else { - } + } else { } } is SessionField.Location -> { if (value.isNotEmpty()) { session.location = realm.getOrCreate(value) - } else { - } + } else { } } is SessionField.Bankroll -> bankrollName = value is SessionField.LimitType -> session.limit = Limit.getInstance(value)?.ordinal @@ -172,14 +195,13 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean is SessionField.SmallBlind -> session.cgSmallBlind = field.parse(value) is SessionField.BigBlind -> session.cgBigBlind = field.parse(value) is SessionField.TableSize -> session.tableSize = TableSize.valueForLabel(value) - is SessionField.SessionType -> { - Session.Type.getValueFromString(value)?.let { type -> - session.type = type.ordinal - } - } is SessionField.TournamentPosition -> session.result?.tournamentFinalPosition = field.parse(value)?.toInt() - is SessionField.TournamentName -> session.tournamentName = realm.getOrCreate(value) + is SessionField.TournamentName -> { + if (value.isNotEmpty()) { + session.tournamentName = realm.getOrCreate(value) + } else { } + } is SessionField.TournamentType -> session.tournamentType = TournamentType.getValueForLabel(value)?.ordinal is SessionField.TournamentNumberOfPlayers -> session.tournamentNumberOfPlayers = @@ -199,26 +221,26 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean session.bankroll = Bankroll.getOrCreate(realm, bankrollName ?: "Import", isLive, currencyCode, currencyRate) - val startDate = session.startDate - val endDate = session.endDate - val net = session.result?.net session.result?.buyin?.let { session.result?.buyin = it + additionalBuyins } + val net = session.result?.net if (startDate != null && endDate != null && net != null) { // valid session // session already in realm, we'd love not put it in Realm before doing the check - if (DataUtils.sessionCount(realm, startDate, endDate, net) == 1) { - return session + val count = DataUtils.sessionCount(realm, startDate!!, endDate!!, net) + if (count == 0) { + val managedSession = realm.copyToRealm(session) + managedSession.startDate = startDate + managedSession.endDate = endDate + return managedSession } else { - Timber.d("Session already exists") + Timber.d("Session already exists(count=$count): sd=$startDate, ed=$endDate, net=$net") } } else { Timber.d("Can't import session: sd=$startDate, ed=$endDate, net=$net") } - session.cleanup() - session.deleteFromRealm() return null } diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt index 6f0876af..1550d399 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt @@ -2,6 +2,14 @@ package net.pokeranalytics.android.util.csv import java.util.* +sealed class TransactionField { + + data class TransactionType( + override var header: String, + override var callback: ((String) -> net.pokeranalytics.android.model.realm.TransactionType?)? = null + ) : DataCSVField + +} /** * The enumeration of Session fields From fe4129cc1af10d0a03ab4d35b1add9dfef71c46b Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 17 Jun 2019 10:47:47 +0200 Subject: [PATCH 110/197] Fixing PBT import --- .../android/util/csv/SessionCSVDescriptor.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt index 3fc15506..5888d53a 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt @@ -91,11 +91,11 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean } val amount = if (buyin != null && buyin!! > 0) { - type = TransactionType.getByValue(TransactionType.Value.DEPOSIT, realm) - buyin - } else if (cashedOut != null && cashedOut!! > 0) { type = TransactionType.getByValue(TransactionType.Value.WITHDRAWAL, realm) - cashedOut!! * -1 + buyin!! * -1 + } else if (cashedOut != null && cashedOut!! > 0) { + type = TransactionType.getByValue(TransactionType.Value.DEPOSIT, realm) + cashedOut } else { null } From 58ac1f336712dde819cddfea501a56e60032fa7e Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 17 Jun 2019 10:54:40 +0200 Subject: [PATCH 111/197] Fixing crash due to missing failed save message for transaction types --- .../android/model/realm/TransactionType.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt index b6c7d4e3..cc00a931 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt @@ -10,6 +10,7 @@ import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.NameManageable +import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.view.Localizable import net.pokeranalytics.android.ui.view.RowRepresentable @@ -120,5 +121,13 @@ open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentab return R.string.transaction_relationship_error } + override fun getFailedSaveMessage(status: SaveValidityStatus): Int { + return when (status) { + SaveValidityStatus.DATA_INVALID -> R.string.operation_type_empty_field_error + SaveValidityStatus.ALREADY_EXISTS -> R.string.duplicate_operation_type_error + else -> super.getFailedSaveMessage(status) + } + } + } From 59e33ada31cdd43f35e446f355aa1330bdf97e11 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 17 Jun 2019 11:34:29 +0200 Subject: [PATCH 112/197] Cleanup + test session before import --- .../android/ui/activity/ImportActivity.kt | 28 +++++++------ .../android/ui/fragment/FeedFragment.kt | 42 +++++++++---------- .../ui/view/rowrepresentable/SettingRow.kt | 5 +-- .../util/extensions/RealmExtensions.kt | 10 ++++- 4 files changed, 45 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt index 215b21b1..37e09ce2 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt @@ -4,13 +4,18 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.os.Bundle +import android.widget.Toast import androidx.fragment.app.FragmentActivity +import io.realm.Realm import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.RequestCode import net.pokeranalytics.android.ui.activity.components.ResultCode import net.pokeranalytics.android.ui.extensions.showAlertDialog import net.pokeranalytics.android.ui.fragment.ImportFragment +import net.pokeranalytics.android.util.billing.AppGuard +import net.pokeranalytics.android.util.extensions.count import timber.log.Timber class ImportActivity : PokerAnalyticsActivity() { @@ -40,26 +45,14 @@ class ImportActivity : PokerAnalyticsActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - Timber.d("//////// data = ${intent?.data}") - intent?.data?.let { this.fileURI = it } setContentView(R.layout.activity_import) -// initUI() requestImportConfirmation() } - override fun onStop() { - super.onStop() - - // Updates the main thread instance with newly inserted data -// val realm = Realm.getDefaultInstance() -// realm.refresh() -// realm.close() - } - private fun initUI() { val fragmentTransaction = supportFragmentManager.beginTransaction() @@ -119,9 +112,18 @@ class ImportActivity : PokerAnalyticsActivity() { private fun requestImportConfirmation() { + val realm = Realm.getDefaultInstance() + val sessionCount = realm.count(Session::class.java) + realm.close() + + if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG + Toast.makeText(this, "Please subscribe!", Toast.LENGTH_LONG).show() + BillingActivity.newInstance(this) + return + } + showAlertDialog(context = this, title = R.string.import_confirmation, showCancelButton = true, positiveAction = { initUI() -// newInstanceForResult(this, uri) }, negativeAction = { finish() }) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt index cd33cc31..9bae8a99 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt @@ -34,8 +34,6 @@ 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 java.text.SimpleDateFormat -import java.util.* class FeedFragment : FilterableFragment(), RowRepresentableDelegate { @@ -62,7 +60,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { private lateinit var feedTransactionAdapter: FeedTransactionRowRepresentableAdapter private lateinit var realmSessions: RealmResults private lateinit var realmTransactions: RealmResults - private lateinit var betaLimitDate: Date +// private lateinit var betaLimitDate: Date private var newSessionCreated: Boolean = false private var adapterHasBeenSet: Boolean = false @@ -208,8 +206,8 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { */ private fun initData() { - val sdf = SimpleDateFormat("dd/M/yyyy hh:mm", Locale.getDefault()) - betaLimitDate = sdf.parse("17/7/2019 10:00") +// val sdf = SimpleDateFormat("dd/M/yyyy hh:mm", Locale.getDefault()) +// betaLimitDate = sdf.parse("17/7/2019 10:00") this.currentFilterable = FilterableType.SESSION val viewManager = SmoothScrollLinearLayoutManager(requireContext()) @@ -282,10 +280,11 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { return } - if (Date().after(betaLimitDate)) { - this.showEndOfBetaMessage() - return - } + // Keep commented code for special versions +// if (Date().after(betaLimitDate)) { +// this.showEndOfBetaMessage() +// return +// } SessionActivity.newInstanceforResult(this, isTournament, requestCode = RequestCode.NEW_SESSION.value) newSessionCreated = true @@ -296,13 +295,12 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { */ private fun createNewTransaction() { - if (Date().after(betaLimitDate)) { - this.showEndOfBetaMessage() - return - } +// if (Date().after(betaLimitDate)) { +// this.showEndOfBetaMessage() +// return +// } EditableDataActivity.newInstanceForResult(this, LiveData.TRANSACTION, null, RequestCode.NEW_TRANSACTION.value) -// EditableDataActivity.newInstance(requireContext(), LiveData.TRANSACTION.ordinal) } /** @@ -317,15 +315,15 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { /** * Show end of beta message + * Keep for possible future uses */ - private fun showEndOfBetaMessage() { - Toast.makeText( - context, - "Beta has ended. Thanks a lot for your participation! Please update with the Google Play version to continue using the app", - Toast.LENGTH_LONG - ).show() - } - +// private fun showEndOfBetaMessage() { +// Toast.makeText( +// context, +// "App version has ended. Thanks a lot for using it! Please update with the Google Play version to continue using the app.", +// Toast.LENGTH_LONG +// ).show() +// } // Filter Handler diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt index adda5f89..7de89ea5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt @@ -37,7 +37,6 @@ enum class SettingRow : RowRepresentable { TERMS_OF_USE, GDPR; - companion object { /** * Return the rows to display for the current session state @@ -46,8 +45,8 @@ enum class SettingRow : RowRepresentable { val rows = ArrayList() rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.information)) - rows.addAll(arrayListOf(VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) -// rows.addAll(arrayListOf(SUBSCRIPTION, VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) +// rows.addAll(arrayListOf(VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) + rows.addAll(arrayListOf(SUBSCRIPTION, VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.follow_us)) rows.addAll(arrayListOf(FOLLOW_US)) diff --git a/app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt b/app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt index aa15c8e6..817a9a43 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt @@ -1,12 +1,18 @@ package net.pokeranalytics.android.util.extensions -import io.realm.* +import io.realm.Realm +import io.realm.RealmModel +import io.realm.RealmResults +import io.realm.Sort import io.realm.kotlin.where import net.pokeranalytics.android.model.interfaces.CountableUsage import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.realm.* -import net.pokeranalytics.android.ui.interfaces.FilterableType + +fun Realm.count(clazz: Class) : Int { + return this.where(clazz).findAll().size +} fun Realm.findById(clazz: Class, id: String) : T? { return this.where(clazz).equalTo("id", id).findFirst() From 2a2198b52de74d0a12310064b997f2e67337f24e Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Mon, 17 Jun 2019 11:58:46 +0200 Subject: [PATCH 113/197] fix lag when opening currencies fragment --- .../android/ui/fragment/CurrenciesFragment.kt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt index 2fa0c3a7..9e2c6eef 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt @@ -44,15 +44,19 @@ class CurrenciesFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataS ) } + private val availableCurrencyLocales = Locale.getAvailableLocales().mapNotNull { + try { + Currency.getInstance(it) + } catch (e: Exception) { + null + } + } + private val availableCurrencies = this.systemCurrencies.filter { !mostUsedCurrencyCodes.contains(it.currencyCode) }.filter { - Locale.getAvailableLocales().filter { locale -> - try { - Currency.getInstance(locale).currencyCode == it.currencyCode - } catch (e: Exception) { - false - } + availableCurrencyLocales.filter { currencyLocale -> + currencyLocale.currencyCode == it.currencyCode }.isNotEmpty() }.sortedBy { it.displayName From ac8c0fdd549e7da43ff53410bc3665b737479cfd Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 17 Jun 2019 12:03:56 +0200 Subject: [PATCH 114/197] Fixing crash when adding a session --- .../android/model/realm/Session.kt | 2 +- .../model/utils/FavoriteSessionFinder.kt | 22 +++++++-------- .../android/ui/fragment/FeedFragment.kt | 3 +- .../android/util/csv/CSVDescriptor.kt | 28 ++++++++++++------- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 293c8fc7..9418a980 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -68,7 +68,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat companion object { - fun newInstance(realm: Realm, isTournament: Boolean, bankroll: Bankroll? = null, managed: Boolean = false): Session { + fun newInstance(realm: Realm, isTournament: Boolean, bankroll: Bankroll? = null, managed: Boolean = true): Session { val session = Session() session.result = Result() if (bankroll != null) { diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt index 57a8e17b..b33cae35 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt @@ -71,27 +71,27 @@ class FavoriteSessionFinder { private const val FAVORITE_SIGNIFICANT_SESSIONS = 15L /** - * Copies the favorite session parameters on the [newSession] + * Copies the favorite session parameters on the [session] */ - fun copyParametersFromFavoriteSession(newSession: Session, location: Location?, context: Context) { + fun copyParametersFromFavoriteSession(session: Session, location: Location?, context: Context) { val favoriteSession = - favoriteSession(newSession.type, location, newSession.realm, context) + favoriteSession(session.type, location, session.realm, context) favoriteSession?.let { fav -> - newSession.limit = fav.limit - newSession.game = fav.game - newSession.bankroll = fav.bankroll - newSession.tableSize = fav.tableSize + session.limit = fav.limit + session.game = fav.game + session.bankroll = fav.bankroll + session.tableSize = fav.tableSize - when (newSession.type) { + when (session.type) { Session.Type.CASH_GAME.ordinal -> { - newSession.cgSmallBlind = fav.cgSmallBlind - newSession.cgBigBlind = fav.cgBigBlind + session.cgSmallBlind = fav.cgSmallBlind + session.cgBigBlind = fav.cgBigBlind } Session.Type.TOURNAMENT.ordinal -> { - newSession.tournamentEntryFee = fav.tournamentEntryFee + session.tournamentEntryFee = fav.tournamentEntryFee } } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt index 9bae8a99..1dc63371 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt @@ -6,7 +6,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.Toast import androidx.core.app.ActivityOptionsCompat import androidx.core.view.isVisible import androidx.interpolator.view.animation.FastOutSlowInInterpolator @@ -275,7 +274,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { val sessionCount = this.feedSessionAdapter.realmResults.size if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG - Toast.makeText(context, "Please subscribe!", Toast.LENGTH_LONG).show() +// Toast.makeText(context, "Please subscribe!", Toast.LENGTH_LONG).show() BillingActivity.newInstance(requireContext()) return } diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt index 36df0fac..5813452f 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt @@ -42,18 +42,26 @@ abstract class DataCSVDescriptor(source: DataSource, vararg el override fun cancel(realm: Realm) { -// Timber.d(">>>>>>> Start delete of ${realmModelIds.size}") - - realm.executeTransaction { - this.realmModelIds.forEach { identifier -> - val data = realm.findById(identifier.clazz, identifier.id) - if (data is Session) { - data.cleanup() - } - data?.deleteFromRealm() + if (realm.isInTransaction) { + this.deleteInsertedFromRealm(realm) + } else { + realm.executeTransaction { + this.deleteInsertedFromRealm(realm) } - this.realmModelIds.clear() } + + } + + private fun deleteInsertedFromRealm(realm: Realm) { + this.realmModelIds.forEach { identifier -> + val data = realm.findById(identifier.clazz, identifier.id) + if (data is Session) { + data.cleanup() + } + data?.deleteFromRealm() + } + this.realmModelIds.clear() + } override fun save(realm: Realm) { From 5af75efe9e9331dede0f8eb934a35548479d970f Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 17 Jun 2019 12:40:17 +0200 Subject: [PATCH 115/197] Subscription refresh + refactoring --- .../android/ui/activity/BillingActivity.kt | 22 ++++++------ .../android/ui/activity/ImportActivity.kt | 2 +- .../android/ui/activity/components/Codes.kt | 4 ++- .../android/ui/fragment/FeedFragment.kt | 2 +- .../android/ui/fragment/SettingsFragment.kt | 36 +++++++++++-------- 5 files changed, 39 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/BillingActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/BillingActivity.kt index 71aafcd9..c60cfd9c 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/BillingActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/BillingActivity.kt @@ -1,18 +1,25 @@ package net.pokeranalytics.android.ui.activity -import android.content.Context +import android.app.Activity import android.content.Intent import android.os.Bundle +import androidx.fragment.app.Fragment import net.pokeranalytics.android.R import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity -import net.pokeranalytics.android.util.billing.AppGuard +import net.pokeranalytics.android.ui.activity.components.RequestCode class BillingActivity : PokerAnalyticsActivity() { companion object { - fun newInstance(context: Context) { - val intent = Intent(context, BillingActivity::class.java) - context.startActivity(intent) + + fun newInstanceForResult(activity: Activity) { + val intent = Intent(activity, BillingActivity::class.java) + activity.startActivityForResult(intent, RequestCode.SUBSCRIPTION.value) + } + + fun newInstanceForResult(fragment: Fragment) { + val intent = Intent(fragment.requireContext(), BillingActivity::class.java) + fragment.startActivityForResult(intent, RequestCode.SUBSCRIPTION.value) } } @@ -21,11 +28,6 @@ class BillingActivity : PokerAnalyticsActivity() { setContentView(R.layout.activity_billing) } - override fun onResume() { - super.onResume() - - } - } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt index 37e09ce2..498a5f86 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt @@ -118,7 +118,7 @@ class ImportActivity : PokerAnalyticsActivity() { if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG Toast.makeText(this, "Please subscribe!", Toast.LENGTH_LONG).show() - BillingActivity.newInstance(this) + BillingActivity.newInstanceForResult(this) return } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt index c8ada486..db99aed0 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt @@ -8,7 +8,9 @@ enum class RequestCode(var value: Int) { NEW_SESSION(800), NEW_TRANSACTION(801), NEW_REPORT(802), - IMPORT(900) + IMPORT(900), + SUBSCRIPTION(901), + CURRENCY(902) } enum class ResultCode(var value: Int) { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt index 1dc63371..82db898e 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt @@ -275,7 +275,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { val sessionCount = this.feedSessionAdapter.realmResults.size if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG // Toast.makeText(context, "Please subscribe!", Toast.LENGTH_LONG).show() - BillingActivity.newInstance(requireContext()) + BillingActivity.newInstanceForResult(this) return } 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 125fac2a..364a50fc 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 @@ -18,6 +18,7 @@ import net.pokeranalytics.android.ui.activity.BillingActivity import net.pokeranalytics.android.ui.activity.CurrenciesActivity import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.GDPRActivity +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.adapter.StaticRowRepresentableDataSource @@ -57,7 +58,6 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta rows } - const val REQUEST_CODE_CURRENCY: Int = 100 } private lateinit var settingsAdapterRow: RowRepresentableAdapter @@ -73,17 +73,25 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (requestCode == REQUEST_CODE_CURRENCY && resultCode == Activity.RESULT_OK) { - data?.let { - Preferences.setCurrencyCode(data.getStringExtra(CurrenciesFragment.INTENT_CURRENCY_CODE), requireContext()) - val realm = Realm.getDefaultInstance() - realm.executeTransaction { - it.where(Session::class.java).isNull("bankroll.currency.code").findAll().forEach { - it.bankrollHasBeenUpdated() - } - } - realm.close() - settingsAdapterRow.refreshRow(SettingRow.CURRENCY) + + when (requestCode) { + RequestCode.CURRENCY.value -> { + if (resultCode == Activity.RESULT_OK) { + data?.let { + Preferences.setCurrencyCode(data.getStringExtra(CurrenciesFragment.INTENT_CURRENCY_CODE), requireContext()) + val realm = Realm.getDefaultInstance() + realm.executeTransaction { + realm.where(Session::class.java).isNull("bankroll.currency.code").findAll().forEach { session -> + session.bankrollHasBeenUpdated() + } + } + realm.close() + settingsAdapterRow.refreshRow(SettingRow.CURRENCY) + } + } + } + RequestCode.SUBSCRIPTION.value -> { + settingsAdapterRow.refreshRow(SettingRow.SUBSCRIPTION) } } } @@ -105,7 +113,7 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta when (row) { SettingRow.SUBSCRIPTION -> { if (!AppGuard.isProUser) { - BillingActivity.newInstance(requireContext()) + BillingActivity.newInstanceForResult(this) } else { this.openPlaystoreAccount() } @@ -113,7 +121,7 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta SettingRow.RATE_APP -> parentActivity?.openPlayStorePage() SettingRow.CONTACT_US -> parentActivity?.openContactMail(R.string.contact) SettingRow.BUG_REPORT -> parentActivity?.openContactMail(R.string.bug_report_subject, Realm.getDefaultInstance().path) - SettingRow.CURRENCY -> CurrenciesActivity.newInstanceForResult(this@SettingsFragment, REQUEST_CODE_CURRENCY) + SettingRow.CURRENCY -> CurrenciesActivity.newInstanceForResult(this@SettingsFragment, RequestCode.CURRENCY.value) SettingRow.FOLLOW_US -> { when (position) { 0 -> parentActivity?.openUrl(URL.BLOG.value) From d65a76964f447b223b463ba920e659696b1f4b2a Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Mon, 17 Jun 2019 12:11:59 +0200 Subject: [PATCH 116/197] wip fix blinds --- .../java/net/pokeranalytics/android/model/realm/Session.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 9418a980..447cd62a 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -619,7 +619,8 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat if (cgBigBlind == null) return cgBigBlind?.let { bb -> val sb = cgSmallBlind ?: bb / 2.0 - blinds = "${currency.symbol} ${sb.formatted()}/${bb.round()}" + val preFormattedBlinds = "${sb.formatted()}/${bb.round()}" + blinds = bb.toCurrency(currency).replace(Regex.fromLiteral("-?\\d+(\\.\\d+)?"), preFormattedBlinds) } } From c731efd2095d08a54d9aff59b1e3e48b391dfec0 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Mon, 17 Jun 2019 13:05:00 +0200 Subject: [PATCH 117/197] fix blinds formatting --- .../android/model/migrations/Patcher.kt | 14 ++++++++++++ .../android/model/realm/Session.kt | 7 +++++- .../android/ui/fragment/CurrenciesFragment.kt | 13 +++-------- .../android/util/Preferences.kt | 22 ++++++++++++------- .../util/extensions/CurrencyExtensions.kt | 11 ++++++++++ .../util/extensions/NumbersExtension.kt | 4 +++- 6 files changed, 51 insertions(+), 20 deletions(-) create mode 100644 app/src/main/java/net/pokeranalytics/android/util/extensions/CurrencyExtensions.kt diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt index 8819d996..2f325f92 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt @@ -19,6 +19,9 @@ class Patcher { Preferences.executeOnce(Preferences.Keys.PATCH_TRANSACTION_TYPES_NAMES, context) { patchDefaultTransactionTypes(context) } + Preferences.executeOnce(Preferences.Keys.PATCH_BLINDS_FORMAT, context) { + patchBlindFormat(context) + } } @@ -59,6 +62,17 @@ class Patcher { realm.close() } + private fun patchBlindFormat(context: Context) { + val realm = Realm.getDefaultInstance() + realm.executeTransaction { + val sessions = realm.where(Session::class.java).findAll() + sessions.forEach { session -> + session.formatBlinds() + } + } + realm.close() + } + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 447cd62a..8c7d977f 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -244,6 +244,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat override var bankroll: Bankroll? = null set(value) { field = value + this.formatBlinds() this.updateRowRepresentation() } @@ -620,7 +621,11 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat cgBigBlind?.let { bb -> val sb = cgSmallBlind ?: bb / 2.0 val preFormattedBlinds = "${sb.formatted()}/${bb.round()}" - blinds = bb.toCurrency(currency).replace(Regex.fromLiteral("-?\\d+(\\.\\d+)?"), preFormattedBlinds) + println("<<<<<< bb.toCurrency(currency) : ${bb.toCurrency(currency)}") + println("<<<<<< preFormattedBlinds : $preFormattedBlinds") + val regex = Regex("-?\\d+(\\.\\d+)?") + blinds = bb.toCurrency(currency).replace(regex, preFormattedBlinds) + println("<<<<<< blinds = $blinds") } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt index 9e2c6eef..bc44a188 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt @@ -17,6 +17,7 @@ import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRow +import net.pokeranalytics.android.util.UserDefaults import java.util.* class CurrenciesFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { @@ -44,19 +45,11 @@ class CurrenciesFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataS ) } - private val availableCurrencyLocales = Locale.getAvailableLocales().mapNotNull { - try { - Currency.getInstance(it) - } catch (e: Exception) { - null - } - } - private val availableCurrencies = this.systemCurrencies.filter { !mostUsedCurrencyCodes.contains(it.currencyCode) }.filter { - availableCurrencyLocales.filter { currencyLocale -> - currencyLocale.currencyCode == it.currencyCode + UserDefaults.availableCurrencyLocales.filter { currencyLocale -> + Currency.getInstance(currencyLocale).currencyCode == it.currencyCode }.isNotEmpty() }.sortedBy { it.displayName diff --git a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt index 6262f7c5..beff0335 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt @@ -27,7 +27,8 @@ class Preferences { ACTIVE_FILTER_ID("ActiveFilterId"), LATEST_PURCHASE("latestPurchase"), PATCH_BREAK("patchBreaks"), - PATCH_TRANSACTION_TYPES_NAMES("patchTransactionTypesNames") + PATCH_TRANSACTION_TYPES_NAMES("patchTransactionTypesNames"), + PATCH_BLINDS_FORMAT("patchBlindFormat") } companion object { @@ -84,14 +85,10 @@ class Preferences { return getString(Keys.CURRENCY_CODE, context) } - private fun getCurrencyLocale(context : Context) : Locale? { + fun getCurrencyLocale(context : Context) : Locale? { getCurrencyCode(context)?.let { currencyCode -> - Locale.getAvailableLocales().filter { - try { - Currency.getInstance(it).currencyCode == currencyCode - } catch (e: Exception) { - false - } + UserDefaults.availableCurrencyLocales.filter { + Currency.getInstance(it).currencyCode == currencyCode }.firstOrNull()?.let { return it } @@ -137,6 +134,15 @@ class UserDefaults private constructor(context: Context) { currency = Preferences.getDefaultCurrency(context) ?: getLocaleCurrency() } + val availableCurrencyLocales = Locale.getAvailableLocales().mapNotNull { + try { + Currency.getInstance(it) + it + } catch (e: Exception) { + null + } + } + /** * Return the locale currency, or en_US if there */ diff --git a/app/src/main/java/net/pokeranalytics/android/util/extensions/CurrencyExtensions.kt b/app/src/main/java/net/pokeranalytics/android/util/extensions/CurrencyExtensions.kt new file mode 100644 index 00000000..baca88f7 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/util/extensions/CurrencyExtensions.kt @@ -0,0 +1,11 @@ +package net.pokeranalytics.android.util.extensions + +import net.pokeranalytics.android.util.UserDefaults +import java.util.* + +val Currency.locale : Locale + get() = + UserDefaults.availableCurrencyLocales.filter { + Currency.getInstance(it).currencyCode == this.currencyCode + }.firstOrNull() ?: Locale.getDefault() + diff --git a/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt b/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt index 39a3f043..cfc80e51 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt @@ -2,6 +2,8 @@ package net.pokeranalytics.android.util.extensions import android.content.Context import net.pokeranalytics.android.R +import net.pokeranalytics.android.util.Preferences +import net.pokeranalytics.android.util.UserDefaults import java.lang.Math.abs import java.math.RoundingMode import java.text.DecimalFormat @@ -50,7 +52,7 @@ fun Double.formatted(): String { fun Double.toCurrency(currency: Currency? = null): String { - val currencyFormatter = NumberFormat.getCurrencyInstance() + val currencyFormatter = NumberFormat.getCurrencyInstance(currency?.locale ?: Locale.getDefault()) currency?.let { currencyFormatter.currency = currency } From f57d6ce2daf68c3ec51cbc1b046cab774554c6d7 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 17 Jun 2019 14:57:45 +0200 Subject: [PATCH 118/197] Fixes refresh issue when updating currency --- .../android/ui/fragment/data/BankrollDataFragment.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/BankrollDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/BankrollDataFragment.kt index eb790102..70152730 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/BankrollDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/BankrollDataFragment.kt @@ -146,9 +146,11 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS override fun onRowValueChanged(value: Any?, row: RowRepresentable) { super.onRowValueChanged(value, row) - // Clear the value when the currency has been updated - if (row == BankrollRow.CURRENCY) { - this.lastRefreshRateCall = 0 + when (row) { + BankrollRow.CURRENCY -> { // Clear the value when the currency has been updated + this.lastRefreshRateCall = 0 + this.rowRepresentableAdapter.notifyDataSetChanged() + } } updateAdapterUI() From 222561f49cc91fa29c8f432e7388212c3916242c Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 17 Jun 2019 14:59:07 +0200 Subject: [PATCH 119/197] Refactor RequestCode use --- .../android/ui/fragment/data/BankrollDataFragment.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/BankrollDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/BankrollDataFragment.kt index 70152730..15ad0686 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/BankrollDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/BankrollDataFragment.kt @@ -9,6 +9,7 @@ import net.pokeranalytics.android.api.CurrencyConverterApi import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.retrofit.CurrencyConverterValue import net.pokeranalytics.android.ui.activity.CurrenciesActivity +import net.pokeranalytics.android.ui.activity.components.RequestCode import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.fragment.CurrenciesFragment @@ -33,10 +34,6 @@ import java.util.* */ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataSource { - companion object { - const val REQUEST_CODE_CURRENCY: Int = 100 - } - // Return the item as a Bankroll object private val bankroll: Bankroll get() { @@ -67,7 +64,7 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) - if (requestCode == REQUEST_CODE_CURRENCY && resultCode == RESULT_OK) { + if (requestCode == RequestCode.CURRENCY.value && resultCode == RESULT_OK) { data?.let { val currencyCode = it.getStringExtra(CurrenciesFragment.INTENT_CURRENCY_CODE) onRowValueChanged(currencyCode, BankrollRow.CURRENCY) @@ -136,7 +133,7 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { when (row) { BankrollRow.CURRENCY -> CurrenciesActivity.newInstanceForResult(this@BankrollDataFragment, - REQUEST_CODE_CURRENCY + RequestCode.CURRENCY.value ) BankrollRow.REFRESH_RATE -> refreshRate() else -> super.onRowSelected(position, row, fromAction) From 2c0a4c89a898927e6ddcce434a1e947a57366b25 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Mon, 17 Jun 2019 15:06:09 +0200 Subject: [PATCH 120/197] formatting currency numbers using the default Locale --- .../pokeranalytics/android/util/extensions/NumbersExtension.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt b/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt index cfc80e51..016edaca 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt @@ -52,7 +52,7 @@ fun Double.formatted(): String { fun Double.toCurrency(currency: Currency? = null): String { - val currencyFormatter = NumberFormat.getCurrencyInstance(currency?.locale ?: Locale.getDefault()) + val currencyFormatter = NumberFormat.getCurrencyInstance(Locale.getDefault()) currency?.let { currencyFormatter.currency = currency } From d357f8c8b4da9cff1d5bf54a74fd7a58a590fb27 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 17 Jun 2019 16:58:55 +0200 Subject: [PATCH 121/197] Added message in subscription window when reaching the max number of sessions + strings update --- .../android/ui/activity/BillingActivity.kt | 26 +++++++++++++++++-- .../android/ui/activity/ImportActivity.kt | 2 +- .../android/ui/fragment/FeedFragment.kt | 2 +- .../android/ui/fragment/SettingsFragment.kt | 2 +- .../ui/fragment/SubscriptionFragment.kt | 19 +++++++++----- app/src/main/res/layout/activity_billing.xml | 17 +++--------- .../main/res/layout/fragment_subscription.xml | 25 +++++++++++++----- app/src/main/res/values/strings.xml | 4 +-- 8 files changed, 64 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/BillingActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/BillingActivity.kt index c60cfd9c..39db989a 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/BillingActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/BillingActivity.kt @@ -7,18 +7,25 @@ import androidx.fragment.app.Fragment import net.pokeranalytics.android.R import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.RequestCode +import net.pokeranalytics.android.ui.fragment.SubscriptionFragment class BillingActivity : PokerAnalyticsActivity() { + private enum class IntentKey(val keyName: String) { + SHOW_MESSAGE("showMessage"), + } + companion object { - fun newInstanceForResult(activity: Activity) { + fun newInstanceForResult(activity: Activity, showSessionMessage: Boolean) { val intent = Intent(activity, BillingActivity::class.java) + intent.putExtra(IntentKey.SHOW_MESSAGE.keyName, showSessionMessage) activity.startActivityForResult(intent, RequestCode.SUBSCRIPTION.value) } - fun newInstanceForResult(fragment: Fragment) { + fun newInstanceForResult(fragment: Fragment, showSessionMessage: Boolean) { val intent = Intent(fragment.requireContext(), BillingActivity::class.java) + intent.putExtra(IntentKey.SHOW_MESSAGE.keyName, showSessionMessage) fragment.startActivityForResult(intent, RequestCode.SUBSCRIPTION.value) } } @@ -26,6 +33,21 @@ class BillingActivity : PokerAnalyticsActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_billing) + initUI() + } + + private fun initUI() { + + val fragmentManager = supportFragmentManager + val fragmentTransaction = fragmentManager.beginTransaction() + val fragment = SubscriptionFragment() + + val showSessionMessage = intent.getBooleanExtra(IntentKey.SHOW_MESSAGE.keyName, false) + + fragmentTransaction.add(R.id.container, fragment) + fragmentTransaction.commit() + fragment.setData(showSessionMessage) + } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt index 498a5f86..2a83c802 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt @@ -118,7 +118,7 @@ class ImportActivity : PokerAnalyticsActivity() { if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG Toast.makeText(this, "Please subscribe!", Toast.LENGTH_LONG).show() - BillingActivity.newInstanceForResult(this) + BillingActivity.newInstanceForResult(this, true) return } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt index 82db898e..e860198e 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt @@ -275,7 +275,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { val sessionCount = this.feedSessionAdapter.realmResults.size if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG // Toast.makeText(context, "Please subscribe!", Toast.LENGTH_LONG).show() - BillingActivity.newInstanceForResult(this) + BillingActivity.newInstanceForResult(this, true) return } 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 364a50fc..f2d79b2d 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 @@ -113,7 +113,7 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta when (row) { SettingRow.SUBSCRIPTION -> { if (!AppGuard.isProUser) { - BillingActivity.newInstanceForResult(this) + BillingActivity.newInstanceForResult(this, false) } else { this.openPlaystoreAccount() } 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 a5b20860..7ebb4063 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 @@ -43,6 +43,7 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene private var pagerAdapter: ScreenSlidePagerAdapter? = null private var selectedProduct: SkuDetails? = null + private var showSessionMessage = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -54,6 +55,10 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene } } + fun setData(showSessionMessage: Boolean) { + this.showSessionMessage = showSessionMessage + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_subscription, container, false) } @@ -89,6 +94,10 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene this.title.text = upgradeString } + if (showSessionMessage) { + this.message.text = getString(R.string.iap_session_message) + } + // Pager // The pager adapter, which provides the pages to the view pager widget. @@ -110,7 +119,7 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene for (i in 1..count) { val view = View(requireContext()) view.background = requireContext().getDrawable(R.drawable.circle_green) - val layoutParam = LinearLayout.LayoutParams(10.px, 10.px) + val layoutParam = LinearLayout.LayoutParams(8.px, 8.px) layoutParam.setMargins(6.px) this.pageIndicator.addView(view, layoutParam) } @@ -202,12 +211,8 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene override fun onPageScrollStateChanged(state: Int) {} override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { - pagerAdapter?.getFragment(position)?.let { - it.updateViewsPosition(-positionOffset * parallax) - } - pagerAdapter?.getFragment(position + 1)?.let { - it.updateViewsPosition((1 - positionOffset) * parallax) - } + pagerAdapter?.getFragment(position)?.updateViewsPosition(-positionOffset * parallax) + pagerAdapter?.getFragment(position + 1)?.updateViewsPosition((1 - positionOffset) * parallax) } override fun onPageSelected(position: Int) { diff --git a/app/src/main/res/layout/activity_billing.xml b/app/src/main/res/layout/activity_billing.xml index 08d1f651..e1701185 100644 --- a/app/src/main/res/layout/activity_billing.xml +++ b/app/src/main/res/layout/activity_billing.xml @@ -1,15 +1,6 @@ - - + android:layout_height="match_parent"> - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_subscription.xml b/app/src/main/res/layout/fragment_subscription.xml index 7791cfb8..e281aa06 100644 --- a/app/src/main/res/layout/fragment_subscription.xml +++ b/app/src/main/res/layout/fragment_subscription.xml @@ -50,37 +50,50 @@ app:layout_constraintTop_toBottomOf="@id/title" tools:text="30 day free trial" /> + + + app:layout_constraintStart_toStartOf="parent" /> Unlimited Track all your poker life by adding as many data as you want Offline first - Poker Analytics is available at all times and the data is yours. Export it at any times. Note: You’re currently in charge of backups, but that will change soon! + Poker Analytics is available at all times and the data is yours. Note: We will soon add exporting capabilities and you’re currently in charge of backups. Thanks for your patience! Private We do not own servers. We do not know anything about your wins and losses. Support @@ -38,6 +38,7 @@ Custom field The item is used in one or more transactions…Please delete the linked transactions first Imported + You\'ve reached the maximum number of free sessions. Please subscribe for unlimited use and don\'t hesitate to tell us how you feel about your current experience! Address Naming suggestions @@ -285,7 +286,6 @@ Net hourly rate Range Export your data to iCloud, get the Pro version, open it, import your data from iCloud. - You\'ve reached the maximum number of sessions. Get a new subscription to get more sessions! iCloud iCloud settings were modified, please wait for synchronization. A backup of your data was found on iCloud, do you want to use it on this device? If yes, the local data from this device will be replaced by the backup and if no, you will keep using the local data from this device and your iCloud account won\'t be modified. From 5da3c7c7eb2ca3a7477646109ec66f589113fd74 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 17 Jun 2019 17:03:59 +0200 Subject: [PATCH 122/197] string changes --- app/src/main/res/values-fr/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index f382b4fe..25c20881 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -18,11 +18,11 @@ Illimité Suivez toute votre vie de joueur en ajoutant autant de données que vous le souhaitez Hors ligne avant tout - Poker Analytics est disponible à tout moment et vos données vous appartiennent. Vous êtes pour l\'instant en charge de faire des sauvegarde mais cela changera dans le futur! + Poker Analytics est disponible à tout moment et vos données vous appartiennent. Vous êtes pour l\'instant en charge d'effectuer des sauvegarde mais cela changera dans le futur! Vie privée Nous ne sauvegardons pas vos données, nous ne savons rien de vos gains ni de vos pertes Support - Nous essayons de répondre le plus vite possible, en français ou en anglais ! + Nous essayons de répondre le plus vite possible, en français mais aussi en anglais ! Chargement, veuillez patienter… Choisissez un type de rapport Choisissez une statistique, ou plusieurs From 48db243eb1d25bad546fef8557ea27bf3a35bcac Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 18 Jun 2019 08:09:01 +0200 Subject: [PATCH 123/197] Fixing strings build issue --- app/src/main/res/values-fr/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 25c20881..5c6a4060 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -18,7 +18,7 @@ Illimité Suivez toute votre vie de joueur en ajoutant autant de données que vous le souhaitez Hors ligne avant tout - Poker Analytics est disponible à tout moment et vos données vous appartiennent. Vous êtes pour l\'instant en charge d'effectuer des sauvegarde mais cela changera dans le futur! + Poker Analytics est disponible à tout moment et vos données vous appartiennent. Vous êtes pour l\'instant en charge d\'effectuer des sauvegarde mais cela changera dans le futur! Vie privée Nous ne sauvegardons pas vos données, nous ne savons rien de vos gains ni de vos pertes Support From 492525d67cababcd95bf17576b921df73a5e2b76 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 18 Jun 2019 08:09:18 +0200 Subject: [PATCH 124/197] Disabling subscriptions --- .../android/ui/fragment/FeedFragment.kt | 52 ++++++++++--------- .../ui/view/rowrepresentable/SettingRow.kt | 4 +- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt index e860198e..47825d1d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt @@ -6,6 +6,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.core.app.ActivityOptionsCompat import androidx.core.view.isVisible import androidx.interpolator.view.animation.FastOutSlowInInterpolator @@ -32,7 +33,8 @@ import net.pokeranalytics.android.ui.interfaces.FilterableType 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 java.text.SimpleDateFormat +import java.util.* class FeedFragment : FilterableFragment(), RowRepresentableDelegate { @@ -59,7 +61,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { private lateinit var feedTransactionAdapter: FeedTransactionRowRepresentableAdapter private lateinit var realmSessions: RealmResults private lateinit var realmTransactions: RealmResults -// private lateinit var betaLimitDate: Date + private lateinit var betaLimitDate: Date private var newSessionCreated: Boolean = false private var adapterHasBeenSet: Boolean = false @@ -205,8 +207,8 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { */ private fun initData() { -// val sdf = SimpleDateFormat("dd/M/yyyy hh:mm", Locale.getDefault()) -// betaLimitDate = sdf.parse("17/7/2019 10:00") + val sdf = SimpleDateFormat("dd/M/yyyy hh:mm", Locale.getDefault()) + betaLimitDate = sdf.parse("17/7/2019 10:00") this.currentFilterable = FilterableType.SESSION val viewManager = SmoothScrollLinearLayoutManager(requireContext()) @@ -272,19 +274,19 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { */ private fun createNewSession(isTournament: Boolean) { - val sessionCount = this.feedSessionAdapter.realmResults.size - if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG -// Toast.makeText(context, "Please subscribe!", Toast.LENGTH_LONG).show() - BillingActivity.newInstanceForResult(this, true) - return - } - - // Keep commented code for special versions -// if (Date().after(betaLimitDate)) { -// this.showEndOfBetaMessage() +// val sessionCount = this.feedSessionAdapter.realmResults.size +// if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG +//// Toast.makeText(context, "Please subscribe!", Toast.LENGTH_LONG).show() +// BillingActivity.newInstanceForResult(this, true) // return // } + // Keep commented code for special versions + if (Date().after(betaLimitDate)) { + this.showEndOfBetaMessage() + return + } + SessionActivity.newInstanceforResult(this, isTournament, requestCode = RequestCode.NEW_SESSION.value) newSessionCreated = true } @@ -294,10 +296,10 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { */ private fun createNewTransaction() { -// if (Date().after(betaLimitDate)) { -// this.showEndOfBetaMessage() -// return -// } + if (Date().after(betaLimitDate)) { + this.showEndOfBetaMessage() + return + } EditableDataActivity.newInstanceForResult(this, LiveData.TRANSACTION, null, RequestCode.NEW_TRANSACTION.value) } @@ -316,13 +318,13 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { * Show end of beta message * Keep for possible future uses */ -// private fun showEndOfBetaMessage() { -// Toast.makeText( -// context, -// "App version has ended. Thanks a lot for using it! Please update with the Google Play version to continue using the app.", -// Toast.LENGTH_LONG -// ).show() -// } + private fun showEndOfBetaMessage() { + Toast.makeText( + context, + "App version has ended. Thanks a lot for using it! Please update with the Google Play version to continue using the app.", + Toast.LENGTH_LONG + ).show() + } // Filter Handler diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt index 7de89ea5..d3f89714 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt @@ -45,8 +45,8 @@ enum class SettingRow : RowRepresentable { val rows = ArrayList() rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.information)) -// rows.addAll(arrayListOf(VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) - rows.addAll(arrayListOf(SUBSCRIPTION, VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) + rows.addAll(arrayListOf(VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) +// rows.addAll(arrayListOf(SUBSCRIPTION, VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.follow_us)) rows.addAll(arrayListOf(FOLLOW_US)) From 9b66e767e3e38b94ff2b1db72375a7292df0a195 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 18 Jun 2019 08:09:53 +0200 Subject: [PATCH 125/197] Bumping version + upgrading androidx.core:core-ktx --- app/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5e354191..67b98e43 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,8 +29,8 @@ android { applicationId "net.pokeranalytics.android" minSdkVersion 23 targetSdkVersion 28 - versionCode 39 - versionName "2.0.2" + versionCode 40 + versionName "2.0.3" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -78,7 +78,7 @@ dependencies { // Android implementation 'androidx.appcompat:appcompat:1.0.2' - implementation 'androidx.core:core-ktx:1.2.0-alpha01' + implementation 'androidx.core:core-ktx:1.2.0-alpha02' implementation 'com.google.android.material:material:1.0.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' From 9fe135e17e5b13041fb51c823d8369b1e3fda455 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 18 Jun 2019 08:26:24 +0200 Subject: [PATCH 126/197] disable CSV import --- app/src/main/AndroidManifest.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b7e5f47c..969194d3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -39,16 +39,16 @@ android:screenOrientation="portrait" android:launchMode="singleTop"> - - - + + + - - - - + + + + - + From 05afd66d73e410c6ad7fa9645a476ce98979e7e4 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 18 Jun 2019 15:43:58 +0200 Subject: [PATCH 127/197] Added ability to duplicate a session --- .../android/model/realm/Session.kt | 18 ++++++++ .../android/ui/activity/SessionActivity.kt | 27 ++++++------ .../FeedSessionRowRepresentableAdapter.kt | 19 +++++--- .../android/ui/fragment/FeedFragment.kt | 43 ++++++++++++++++--- .../android/ui/fragment/SessionFragment.kt | 26 ++++++++--- .../ui/view/ContextMenuRecyclerView.kt | 38 ++++++++++++++++ app/src/main/res/layout/fragment_feed.xml | 3 +- .../layout/row_bottom_sheet_grid_title.xml | 1 + app/src/main/res/layout/row_session_view.xml | 3 +- app/src/main/res/layout/row_title.xml | 2 +- app/src/main/res/layout/row_title_arrow.xml | 2 +- app/src/main/res/layout/row_title_check.xml | 2 +- .../main/res/layout/row_title_icon_arrow.xml | 2 +- app/src/main/res/menu/menu_session.xml | 8 ++++ app/src/main/res/values/styles.xml | 7 ++- 15 files changed, 164 insertions(+), 37 deletions(-) create mode 100644 app/src/main/java/net/pokeranalytics/android/ui/view/ContextMenuRecyclerView.kt create mode 100644 app/src/main/res/menu/menu_session.xml diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 8c7d977f..8944468e 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -658,6 +658,24 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } + fun duplicate() : Session { + + val copy = Session.newInstance(this.realm, this.isTournament(), this.bankroll) + + copy.game = this.game + copy.limit = this.limit + copy.cgSmallBlind = this.cgSmallBlind + copy.cgBigBlind = this.cgBigBlind + copy.tournamentEntryFee = this.tournamentEntryFee + copy.tournamentFeatures = this.tournamentFeatures + copy.tournamentName = this.tournamentName + copy.tournamentType = this.tournamentType + copy.tableSize = this.tableSize + copy.numberOfTables = this.numberOfTables + + return copy + } + @Ignore override val viewType: Int = RowViewType.ROW_SESSION.ordinal diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/SessionActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/SessionActivity.kt index e082fb49..602762c9 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/SessionActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/SessionActivity.kt @@ -14,32 +14,32 @@ class SessionActivity: PokerAnalyticsActivity() { enum class IntentKey(val keyName : String) { IS_TOURNAMENT("IS_TOURNAMENT"), + DUPLICATE("DUPLICATE"), SESSION_ID("SESSION_ID"); } companion object { - fun newInstance(context: Context, isTournament: Boolean? = false, sessionId: String? = "") { - val intent = Intent(context, SessionActivity::class.java) - isTournament?.let { - intent.putExtra(IntentKey.IS_TOURNAMENT.keyName, isTournament) - } - sessionId?.let { - intent.putExtra(IntentKey.SESSION_ID.keyName, sessionId) - } + fun newInstance(context: Context, isTournament: Boolean? = false, sessionId: String? = "", duplicate: Boolean = false) { + val intent = this.intent(context, isTournament, sessionId, duplicate) context.startActivity(intent) } - fun newInstanceforResult(fragment: Fragment, isTournament: Boolean? = false, sessionId: String? = "", requestCode: Int) { - val intent = Intent(fragment.requireContext(), SessionActivity::class.java) + fun newInstanceforResult(fragment: Fragment, isTournament: Boolean? = false, sessionId: String? = "", duplicate: Boolean = false, requestCode: Int) { + val intent = this.intent(fragment.requireContext(), isTournament, sessionId, duplicate) + fragment.startActivityForResult(intent, requestCode) + } + + private fun intent(context: Context, isTournament: Boolean? = false, sessionId: String? = "", duplicate: Boolean = false) : Intent { + val intent = Intent(context, SessionActivity::class.java) isTournament?.let { intent.putExtra(IntentKey.IS_TOURNAMENT.keyName, isTournament) } + intent.putExtra(IntentKey.DUPLICATE.keyName, duplicate) sessionId?.let { intent.putExtra(IntentKey.SESSION_ID.keyName, sessionId) } - - fragment.startActivityForResult(intent, requestCode) + return intent } } @@ -62,8 +62,9 @@ class SessionActivity: PokerAnalyticsActivity() { private fun initUI() { val sessionId = intent.getStringExtra(IntentKey.SESSION_ID.keyName) val isTournament = intent.getBooleanExtra(IntentKey.IS_TOURNAMENT.keyName, false) + val duplicate = intent.getBooleanExtra(IntentKey.DUPLICATE.keyName, false) val fragment = sessionFragment as SessionFragment - fragment.setData(isTournament, sessionId) + fragment.setData(isTournament, sessionId, duplicate) } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedSessionRowRepresentableAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedSessionRowRepresentableAdapter.kt index 405167e7..849487ec 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedSessionRowRepresentableAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedSessionRowRepresentableAdapter.kt @@ -8,7 +8,6 @@ import androidx.appcompat.widget.AppCompatTextView import androidx.recyclerview.widget.RecyclerView import io.realm.RealmResults import kotlinx.android.synthetic.main.row_feed_session.view.* -import net.pokeranalytics.android.R import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.ui.view.BindableHolder import net.pokeranalytics.android.ui.view.RowViewType @@ -43,6 +42,7 @@ class FeedSessionRowRepresentableAdapter( * Display a session view */ inner class RowSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { + fun bind(position: Int, row: Session?, adapter: FeedSessionRowRepresentableAdapter) { itemView.sessionRow.setData(row as Session) @@ -50,6 +50,10 @@ class FeedSessionRowRepresentableAdapter( adapter.delegate?.onRowSelected(position, row) } itemView.sessionRow.setOnClickListener(listener) + + itemView.sessionRow.setOnLongClickListener { + itemView.showContextMenu() + } } } @@ -59,7 +63,7 @@ class FeedSessionRowRepresentableAdapter( inner class HeaderTitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { fun bind(title: String) { // Title - itemView.findViewById(R.id.title)?.let { + itemView.findViewById(net.pokeranalytics.android.R.id.title)?.let { it.text = title } } @@ -67,10 +71,10 @@ class FeedSessionRowRepresentableAdapter( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return if (viewType == RowViewType.ROW_SESSION.ordinal) { - val layout = LayoutInflater.from(parent.context).inflate(R.layout.row_feed_session, parent, false) + val layout = LayoutInflater.from(parent.context).inflate(net.pokeranalytics.android.R.layout.row_feed_session, parent, false) RowSessionViewHolder(layout) } else { - val layout = LayoutInflater.from(parent.context).inflate(R.layout.row_header_title, parent, false) + val layout = LayoutInflater.from(parent.context).inflate(net.pokeranalytics.android.R.layout.row_header_title, parent, false) HeaderTitleViewHolder(layout) } @@ -104,7 +108,7 @@ class FeedSessionRowRepresentableAdapter( // If the header has no date, it's a pending session return if (sortedHeaders[position] == null) { - context.getString(R.string.pending) + context.getString(net.pokeranalytics.android.R.string.pending) } else { // Else, return the formatted date val realmHeaderPosition = if (pendingRealmResults.size > 0) sortedHeaders.keys.indexOf(position) - 1 else sortedHeaders.keys.indexOf(position) @@ -114,6 +118,11 @@ class FeedSessionRowRepresentableAdapter( return NULL_TEXT } + fun sessionIdForPosition(position: Int): String? { + val session = this.getSessionForPosition(position) + return session?.id + } + /** * Get real index */ diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt index 47825d1d..dc1608ad 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt @@ -3,9 +3,7 @@ package net.pokeranalytics.android.ui.fragment import android.app.Activity.RESULT_OK import android.content.Intent import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup +import android.view.* import android.widget.Toast import androidx.core.app.ActivityOptionsCompat import androidx.core.view.isVisible @@ -17,6 +15,7 @@ import io.realm.Sort import io.realm.kotlin.where import kotlinx.android.synthetic.main.fragment_feed.* import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.interfaces.Editable import net.pokeranalytics.android.model.realm.Filter @@ -30,13 +29,14 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.fragment.components.FilterableFragment import net.pokeranalytics.android.ui.interfaces.FilterActivityRequestCode import net.pokeranalytics.android.ui.interfaces.FilterableType +import net.pokeranalytics.android.ui.view.ContextMenuRecyclerView import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager import net.pokeranalytics.android.util.Preferences +import timber.log.Timber import java.text.SimpleDateFormat import java.util.* - class FeedFragment : FilterableFragment(), RowRepresentableDelegate { private enum class Tab { @@ -91,6 +91,35 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { return inflater.inflate(R.layout.fragment_feed, container, false) } + override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) { + super.onCreateContextMenu(menu, v, menuInfo) + + if (v?.id == R.id.recyclerView) { + activity?.menuInflater?.inflate(R.menu.menu_session, menu) + } + + } + + override fun onContextItemSelected(item: MenuItem?): Boolean { + + when (item?.itemId) { + R.id.duplicate -> { + val info = item.menuInfo as ContextMenuRecyclerView.RecyclerViewContextMenuInfo + Timber.d("info = $info") + + val sessionId = this.feedSessionAdapter.sessionIdForPosition(info.position) + if (sessionId != null) { + createNewSession(true, sessionId = sessionId, duplicate = true) + } else { + throw PAIllegalStateException("Session not found for duplicate at position: ${info.position}") + } + } + else -> { } + } + + return true + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initUI() @@ -160,6 +189,8 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { */ private fun initUI() { + registerForContextMenu(this.recyclerView) + disclaimerContainer.isVisible = Preferences.shouldShowDisclaimer(requireContext()) disclaimerDismiss.setOnClickListener { @@ -272,7 +303,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { /** * Create a new cash game */ - private fun createNewSession(isTournament: Boolean) { + private fun createNewSession(isTournament: Boolean, sessionId: String? = null, duplicate: Boolean = false) { // val sessionCount = this.feedSessionAdapter.realmResults.size // if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG @@ -287,7 +318,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { return } - SessionActivity.newInstanceforResult(this, isTournament, requestCode = RequestCode.NEW_SESSION.value) + SessionActivity.newInstanceforResult(this, isTournament, sessionId = sessionId, duplicate = duplicate, requestCode = RequestCode.NEW_SESSION.value) newSessionCreated = true } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt index 335aa4f4..e62eabc5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt @@ -61,14 +61,28 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate { /** * Set fragment data */ - fun setData(isTournament: Boolean, sessionId: String) { + fun setData(isTournament: Boolean, sessionId: String? = null, duplicate: Boolean) { val realm = getRealm() - val sessionRealm = realm.findById(sessionId) - if (sessionRealm != null) { - currentSession = sessionRealm - sessionHasBeenCustomized = true - } else { + if (sessionId != null) { + + val sessionRealm = realm.findById(sessionId) + if (sessionRealm != null) { + + if (duplicate) { // duplicate session + realm.executeTransaction { + val session = sessionRealm.duplicate() + currentSession = session + } + sessionHasBeenCustomized = false + } else { // show existing session + currentSession = sessionRealm + sessionHasBeenCustomized = true + } + } else { + throw PAIllegalStateException("Session cannot be null here, session id = $sessionId") + } + } else { // create new session realm.executeTransaction { executeRealm -> currentSession = Session.newInstance(executeRealm, isTournament) FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, null, requireContext()) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/ContextMenuRecyclerView.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/ContextMenuRecyclerView.kt new file mode 100644 index 00000000..07dbdb18 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/ContextMenuRecyclerView.kt @@ -0,0 +1,38 @@ +package net.pokeranalytics.android.ui.view + +import android.content.Context +import android.util.AttributeSet +import android.view.ContextMenu +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import timber.log.Timber + + +class ContextMenuRecyclerView : RecyclerView { + + constructor(context: Context, attributeSet: AttributeSet?, defStyle: Int) : super(context, attributeSet, defStyle) + constructor(context: Context, attributeSet: AttributeSet?) : super(context, attributeSet) + constructor(context: Context) : super(context) + + private var mContextMenuInfo: RecyclerViewContextMenuInfo? = null + + override fun getContextMenuInfo(): ContextMenu.ContextMenuInfo? { + return mContextMenuInfo + } + + override fun showContextMenuForChild(originalView: View): Boolean { + val longPressPosition = getChildAdapterPosition(originalView) + Timber.d("longPressPosition = $longPressPosition") + if (longPressPosition >= 0) { + val longPressId = adapter!!.getItemId(longPressPosition) + Timber.d("longPressId = $longPressId") + mContextMenuInfo = RecyclerViewContextMenuInfo(longPressPosition, longPressId) + return super.showContextMenuForChild(originalView) + } + return false + } + + class RecyclerViewContextMenuInfo(val position: Int, val id: Long) : ContextMenu.ContextMenuInfo + +} + diff --git a/app/src/main/res/layout/fragment_feed.xml b/app/src/main/res/layout/fragment_feed.xml index 9ee9dc14..b8000803 100644 --- a/app/src/main/res/layout/fragment_feed.xml +++ b/app/src/main/res/layout/fragment_feed.xml @@ -57,7 +57,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/appBar" /> - - + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 23e128e8..c0562ef6 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -17,7 +17,7 @@ @style/PokerAnalyticsTheme.Toolbar @style/PokerAnalyticsTheme.BottomAppBar @style/PokerAnalyticsTheme.EditText - @style/PokerAnalyticsTheme.TextView + @style/PokerAnalyticsTheme.AlertDialog @style/PokerAnalyticsTheme.Chip @style/PokerAnalyticsTheme.TabLayout @@ -83,6 +83,11 @@ @font/roboto + +