diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index da086eb8..f033e2d5 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -47,7 +47,7 @@ class PokerAnalyticsApplication : Application() { Realm.init(this) val realmConfiguration = RealmConfiguration.Builder() .name(Realm.DEFAULT_REALM_NAME) - .schemaVersion(9) + .schemaVersion(10) .migration(PokerAnalyticsMigration()) .initialData(Seed(this)) .build() 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 e9ade914..3c884c1b 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 @@ -227,6 +227,18 @@ class PokerAnalyticsMigration : RealmMigration { currentVersion++ } + + // Migrate to version 10 + if (currentVersion == 9) { + schema.get("Session")?.addField("handsCount", Int::class.java) + + val configSchema = schema.create("Configuration") + configSchema.addField("liveDealtHandsPerHour", Int::class.java) + configSchema.addField("onlineDealtHandsPerHour", Int::class.java) + + currentVersion++ + } + } override fun equals(other: Any?): Boolean { @@ -236,4 +248,5 @@ class PokerAnalyticsMigration : RealmMigration { override fun hashCode(): Int { return RealmMigration::javaClass.hashCode() } + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Configuration.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Configuration.kt new file mode 100644 index 00000000..6ff53f2c --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Configuration.kt @@ -0,0 +1,23 @@ +package net.pokeranalytics.android.model.realm + +import io.realm.Realm +import io.realm.RealmObject + +class Configuration : RealmObject() { + + companion object { + + fun getConfiguration(realm: Realm): Configuration { + realm.where(Configuration::class.java).findFirst()?.let { + return it + } + return Configuration() + } + + } + + var liveDealtHandsPerHour: Int = 250 + + var onlineDealtHandsPerHour: Int = 500 + +} \ 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 3a67adf6..ded20ea9 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 @@ -333,6 +333,13 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim // The custom fields values var customFieldEntries: RealmList = RealmList() + // The number of hands played during the sessions + var handsCount: Int? = null + set(value) { + field = value + this.computeStats() + } + fun bankrollHasBeenUpdated() { formatBlinds() } @@ -380,11 +387,6 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim // Stats - @Ignore - val ONLINE_PLAYER_HANDS_PER_HOUR = 500.0 - @Ignore - val LIVE_PLAYER_HANDS_PER_HOUR = 250.0 - /** * The net result in big blinds */ @@ -405,12 +407,14 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim @Ignore var estimatedHands: Double = 0.0 get() { + this.handsCount?.let { + return it.toDouble() + } val noh = this.numberOfHandsPerHour val hd = this.hourlyDuration return noh * hd } - // DatedValue @Ignore @@ -455,7 +459,8 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim val numberOfHandsPerHour: Double get() { val tableSize = this.tableSize ?: 9 // 9 is the default table size if null - val playerHandsPerHour = if (this.isLive) LIVE_PLAYER_HANDS_PER_HOUR else ONLINE_PLAYER_HANDS_PER_HOUR + val config = Configuration.getConfiguration(this.realm) + val playerHandsPerHour = if (this.isLive) config.liveDealtHandsPerHour else config.onlineDealtHandsPerHour return playerHandsPerHour / tableSize.toDouble() } @@ -982,6 +987,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim } SessionPropertiesRow.TOURNAMENT_NAME -> tournamentName?.name ?: NULL_TEXT SessionPropertiesRow.HANDS -> this.handHistories?.size.toString() + SessionPropertiesRow.HANDS_COUNT -> this.handsCountFormatted(context) is CustomField -> { customFieldEntries.find { it.customField?.id == row.id }?.let { customFieldEntry -> return customFieldEntry.getFormattedValue(currency) @@ -992,6 +998,11 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim } } + private fun handsCountFormatted(context: Context): String { + return this.handsCount?.toString() ?: + "${estimatedHands.toInt()} (${context.getString(R.string.estimated)})" + } + fun clearBuyinCashedOut() { this.result?.buyin = null this.result?.cashout = null 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 468b598b..d34b9a41 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 @@ -20,6 +20,7 @@ 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.realm.ComputableResult +import net.pokeranalytics.android.model.realm.Configuration import net.pokeranalytics.android.model.realm.Filter import net.pokeranalytics.android.ui.fragment.components.FilterableFragment import net.pokeranalytics.android.ui.fragment.components.RealmAsyncListener @@ -68,7 +69,9 @@ class StatisticsFragment : FilterableFragment(), RealmAsyncListener { initUI() this.currentFilterable = FilterableType.SESSION applyFilter() - listenRealmChanges(this, ComputableResult::class.java) + + addRealmChangeListener(this, Configuration::class.java) + addRealmChangeListener(this, ComputableResult::class.java) } private fun initUI() { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/RealmFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/RealmFragment.kt index c24bd928..e66dbc6b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/RealmFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/RealmFragment.kt @@ -8,6 +8,7 @@ import io.realm.Realm import io.realm.RealmModel import io.realm.RealmResults import kotlinx.coroutines.Dispatchers +import net.pokeranalytics.android.exceptions.PAIllegalStateException import timber.log.Timber import kotlin.coroutines.CoroutineContext @@ -40,31 +41,53 @@ open class RealmFragment : BaseFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { realm = Realm.getDefaultInstance() - this.observedEntities.forEach { - val realmResults = realm.where(it).findAll() - - realmResults.addChangeListener { t, _ -> - this.entitiesChanged(it, t) - } - - this.observedRealmResults.add(realmResults) - } +// this.observedEntities.forEach { +// val realmResults = realm.where(it).findAll() +// +// realmResults.addChangeListener { t, _ -> +// this.entitiesChanged(it, t) +// } +// +// this.observedRealmResults.add(realmResults) +// } return super.onCreateView(inflater, container, savedInstanceState) } - fun listenRealmChanges(listener: RealmAsyncListener, clazz: Class) { + /** + * Get the realm instance + */ + fun getRealm(): Realm { + return this.realm + } - this.changeListener = listener + fun addRealmChangeListener(listener: RealmAsyncListener, clazz: Class) { + + if (this.changeListener != null && this.changeListener != listener) { + throw PAIllegalStateException("You cannot use a different listener") + } - this.realmResults = this.realm.where(clazz).findAllAsync() - this.realmResults?.addChangeListener { t, _ -> + this.changeListener = listener + val results = this.realm.where(clazz).findAllAsync() + results.addChangeListener { t, _ -> Timber.d("Realm changes: ${realmResults?.size}, $this") this.changeListener?.asyncListenedEntityChange(t.realm) } - + this.observedRealmResults.add(results) } +// fun listenRealmChanges(listener: RealmAsyncListener, clazz: Class) { +// +// this.changeListener = listener +// +// this.realmResults = this.realm.where(clazz).findAllAsync() +// this.realmResults?.addChangeListener { t, _ -> +// Timber.d("Realm changes: ${realmResults?.size}, $this") +// this.changeListener?.asyncListenedEntityChange(t.realm) +// } +// +// } + override fun onDestroyView() { super.onDestroyView() @@ -76,17 +99,10 @@ open class RealmFragment : BaseFragment() { this.realmResults?.removeAllChangeListeners() } - /** - * Get the realm instance - */ - fun getRealm(): Realm { - return this.realm - } - /** * A list of RealmModel classes to observe */ - open val observedEntities: List> = listOf() +// open val observedEntities: List> = listOf() /** * The method called when a change happened in any RealmResults diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt index 83110ac3..1e40c533 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt @@ -19,6 +19,7 @@ import net.pokeranalytics.android.model.Criteria import net.pokeranalytics.android.model.combined import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.realm.ComputableResult +import net.pokeranalytics.android.model.realm.Configuration import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource @@ -86,7 +87,9 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable super.onViewCreated(view, savedInstanceState) initData() initUI() - listenRealmChanges(this, ComputableResult::class.java) + + addRealmChangeListener(this, Configuration::class.java) + addRealmChangeListener(this, ComputableResult::class.java) } override fun onDestroyView() { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/settings/DealtHandsPerHourFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/settings/DealtHandsPerHourFragment.kt new file mode 100644 index 00000000..95468aaf --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/settings/DealtHandsPerHourFragment.kt @@ -0,0 +1,11 @@ +package net.pokeranalytics.android.ui.modules.settings + +import net.pokeranalytics.android.ui.fragment.components.BaseFragment + +class DealtHandsPerHourFragment : BaseFragment() { + + + + + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rows/SessionPropertiesRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rows/SessionPropertiesRow.kt index 5eb0f9ff..296695f6 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rows/SessionPropertiesRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rows/SessionPropertiesRow.kt @@ -40,7 +40,8 @@ enum class SessionPropertiesRow : RowRepresentable { BREAK_TIME, COMMENT, - HANDS; + HANDS, + HANDS_COUNT; companion object { /** @@ -172,6 +173,7 @@ enum class SessionPropertiesRow : RowRepresentable { BREAK_TIME -> R.string.break_time COMMENT -> R.string.comment HANDS -> R.string.hands + HANDS_COUNT -> R.string.hands_count } } @@ -181,14 +183,15 @@ enum class SessionPropertiesRow : RowRepresentable { NET_RESULT, PRIZE, POSITION, PLAYERS, CASHED_OUT, INITIAL_BUY_IN, BUY_IN, TIPS, GAME, BLINDS, LOCATION, BANKROLL, TABLE_SIZE, COMMENT, TOURNAMENT_TYPE, TOURNAMENT_NAME, TOURNAMENT_FEATURE, HANDS, - START_DATE, END_DATE, BREAK_TIME -> RowViewType.TITLE_VALUE.ordinal + START_DATE, END_DATE, BREAK_TIME, HANDS_COUNT -> RowViewType.TITLE_VALUE.ordinal } } override val bottomSheetType: BottomSheetType get() { return when (this) { - NET_RESULT, CASHED_OUT, INITIAL_BUY_IN, BREAK_TIME, POSITION, PLAYERS, PRIZE -> BottomSheetType.NUMERIC_TEXT + NET_RESULT, CASHED_OUT, INITIAL_BUY_IN, BREAK_TIME, POSITION, PLAYERS, + PRIZE, HANDS_COUNT -> BottomSheetType.NUMERIC_TEXT BUY_IN, TIPS -> BottomSheetType.SUM BLINDS -> BottomSheetType.DOUBLE_EDIT_TEXT GAME -> BottomSheetType.LIST_GAME @@ -269,6 +272,11 @@ enum class SessionPropertiesRow : RowRepresentable { ) ) } + HANDS_COUNT -> { + arrayListOf( + RowRepresentableEditDescriptor(inputType = InputType.TYPE_CLASS_NUMBER) + ) + } GAME -> { val limit: Int? by map val defaultValue: Any? by map diff --git a/app/src/main/res/layout/fragment_dealt_hands_config.xml b/app/src/main/res/layout/fragment_dealt_hands_config.xml new file mode 100644 index 00000000..fd844d40 --- /dev/null +++ b/app/src/main/res/layout/fragment_dealt_hands_config.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + \ 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 b750faf0..f673ef0b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -812,5 +812,7 @@ Show tips on front page App tips ITM ratio + Hands count + estimated