Complext blinds for hand histories

blinds
Laurent 3 years ago
parent 546e7a5777
commit f48683d683
  1. 2
      app/src/main/AndroidManifest.xml
  2. 2
      app/src/main/java/net/pokeranalytics/android/model/extensions/SessionExtensions.kt
  3. 52
      app/src/main/java/net/pokeranalytics/android/model/handhistory/HandSetup.kt
  4. 71
      app/src/main/java/net/pokeranalytics/android/model/interfaces/StakesHolder.kt
  5. 2
      app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt
  6. 28
      app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt
  7. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/ComputableResult.kt
  8. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt
  9. 121
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  10. 106
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt
  11. 4
      app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt
  12. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt
  13. 32
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetStakesFragment.kt
  14. 3
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/editor/EditorAdapter.kt
  15. 4
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ActionList.kt
  16. 9
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/EditorViewModel.kt
  17. 8
      app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt
  18. 10
      app/src/main/java/net/pokeranalytics/android/util/FakeDataManager.kt
  19. 64
      app/src/main/java/net/pokeranalytics/android/util/csv/PACSVDescriptor.kt
  20. 41
      app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt
  21. 7
      app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt
  22. 1
      app/src/main/res/layout/bottom_sheet_stakes.xml

@ -61,7 +61,7 @@
android:name="net.pokeranalytics.android.ui.modules.session.SessionActivity" android:name="net.pokeranalytics.android.ui.modules.session.SessionActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:windowSoftInputMode="adjustNothing" /> android:windowSoftInputMode="stateAlwaysHidden|adjustNothing" />
<!-- No screenOrientation="portrait" to fix Oreo crash --> <!-- No screenOrientation="portrait" to fix Oreo crash -->
<activity <activity

@ -75,7 +75,7 @@ fun Session.getFormattedGameType(context: Context): String {
parameters.add(context.getString(R.string.tournament).capitalize()) parameters.add(context.getString(R.string.tournament).capitalize())
} }
} else { } else {
if (cgSmallBlind != null && cgBigBlind != null) { if (this.cgAnte != null && this.cgBlinds != null) {
parameters.add(getFormattedStakes()) parameters.add(getFormattedStakes())
} }
game?.let { game?.let {

@ -36,36 +36,11 @@ class HandSetup {
} }
private fun configure(handHistory: HandHistory) {
this.smallBlind = handHistory.smallBlind
this.bigBlind = handHistory.bigBlind
this.bigBlindAnte = handHistory.bigBlindAnte
this.ante = handHistory.ante
this.tableSize = handHistory.numberOfPlayers
}
/***
* Configures the Hand Setup with a [session]
* [attached] denotes if the HandHistory must be directly linked to the session
*/
private fun configure(session: Session, attached: Boolean) {
if (attached) {
this.session = session
}
if (session.endDate == null) {
this.game = session.game // we don't want to force the max number of cards if unsure
}
this.type = session.sessionType
this.smallBlind = session.cgSmallBlind
this.bigBlind = session.cgBigBlind
this.tableSize = session.tableSize
}
var type: Session.Type? = null var type: Session.Type? = null
var smallBlind: Double? = null var blinds: String? = null
var bigBlind: Double? = null // var bigBlind: Double? = null
var ante: Double? = null var ante: Double? = null
@ -84,6 +59,29 @@ class HandSetup {
this.straddlePositions.clear() this.straddlePositions.clear()
} }
private fun configure(handHistory: HandHistory) {
this.blinds = handHistory.blinds
this.bigBlindAnte = handHistory.bigBlindAnte
this.ante = handHistory.ante
this.tableSize = handHistory.numberOfPlayers
}
/***
* Configures the Hand Setup with a [session]
* [attached] denotes if the HandHistory must be directly linked to the session
*/
private fun configure(session: Session, attached: Boolean) {
if (attached) {
this.session = session
}
if (session.endDate == null) {
this.game = session.game // we don't want to force the max number of cards if unsure
}
this.type = session.sessionType
this.blinds = session.cgBlinds
this.tableSize = session.tableSize
}
/*** /***
* This method sorts the straddle positions in their natural order * This method sorts the straddle positions in their natural order
* If the straddle position contains the button, we're usually in a Mississipi straddle, * If the straddle position contains the button, we're usually in a Mississipi straddle,

@ -0,0 +1,71 @@
package net.pokeranalytics.android.model.interfaces
import net.pokeranalytics.android.model.realm.Bankroll
import net.pokeranalytics.android.util.BLIND_SEPARATOR
import net.pokeranalytics.android.util.UserDefaults
import net.pokeranalytics.android.util.extensions.formatted
import java.text.NumberFormat
import java.text.ParseException
interface StakesHolder {
companion object {
private const val cbSeparator = ";"
private const val cbAnte = "A="
private const val cbBlinds = "B="
private const val cbCode = "C="
}
val ante: Double?
val blinds: String?
val biggestBet: Double?
val stakes: String?
val bankroll: Bankroll?
fun setHolderStakes(stakes: String?)
fun setHolderBiggestBet(biggestBet: Double?)
val blindValues: List<Double>
get() {
this.blinds?.let { blinds ->
val blindsSplit = blinds.split(BLIND_SEPARATOR)
return blindsSplit.mapNotNull {
try {
NumberFormat.getInstance().parse(it)?.toDouble()
} catch (e: ParseException) {
null
}
}
}
return listOf()
}
fun generateStakes() {
if (this.ante == null && this.ante == null) {
setHolderStakes(null)
return
}
val components = arrayListOf<String>()
this.blinds?.let { components.add("${cbBlinds}${it}") }
this.ante?.let { components.add("${cbAnte}${it.formatted}") }
val code = this.bankroll?.currency?.code ?: UserDefaults.currency.currencyCode
components.add("${cbCode}${code}")
setHolderStakes(components.joinToString(cbSeparator))
}
fun defineHighestBet() {
val bets = arrayListOf<Double>()
this.ante?.let { bets.add(it) }
bets.addAll(this.blindValues)
setHolderBiggestBet(bets.maxOrNull())
}
}

@ -128,7 +128,7 @@ class Patcher {
realm.executeTransaction { realm.executeTransaction {
val sessions = realm.where(Session::class.java).findAll() val sessions = realm.where(Session::class.java).findAll()
sessions.forEach { session -> sessions.forEach { session ->
val blinds = arrayListOf(session.cgSmallBlind, session.cgBigBlind).filterNotNull() val blinds = arrayListOf(session.cgOldSmallBlind, session.cgOldBigBlind).filterNotNull()
val blindsFormatted = blinds.map { NumberFormat.getInstance().format(it) } val blindsFormatted = blinds.map { NumberFormat.getInstance().format(it) }
if (blindsFormatted.isNotEmpty()) { if (blindsFormatted.isNotEmpty()) {
session.cgBlinds = blindsFormatted.joinToString(BLIND_SEPARATOR) session.cgBlinds = blindsFormatted.joinToString(BLIND_SEPARATOR)

@ -254,13 +254,27 @@ class PokerAnalyticsMigration : RealmMigration {
// Migrate to version 12 // Migrate to version 12
if (currentVersion == 11) { if (currentVersion == 11) {
schema.get("Session")?.addField("cgAnte", Double::class.java)
?.setNullable("cgAnte", true) schema.get("Session")?.let { ss ->
schema.get("Session")?.addField("cgBiggestBet", Double::class.java)
?.setNullable("cgBiggestBet", true) ss.addField("cgAnte", Double::class.java)
schema.get("Session")?.addField("cgStakes", String::class.java) ?.setNullable("cgAnte", true)
schema.get("Session")?.addField("cgBlinds", String::class.java) ss.addField("cgBiggestBet", Double::class.java)
schema.get("Session")?.removeField("blinds") ?.setNullable("cgBiggestBet", true)
ss.addField("cgStakes", String::class.java)
ss.addField("cgBlinds", String::class.java)
ss.removeField("blinds")
ss.renameField("cgSmallBlind", "cgOldSmallBlind")
ss.renameField("cgBigBlind", "cgOldBigBlind")
}
schema.get("HandHistory")?.let { hs ->
hs.addField("cgStakes", String::class.java)
hs.addField("cgBlinds", String::class.java)
hs.renameField("smallBlind", "oldSmallBlind")
hs.renameField("bigBlind", "oldBigBlind")
}
currentVersion++ currentVersion++
} }

@ -36,7 +36,7 @@ open class ComputableResult : RealmObject(), Filterable {
} }
this.bbNet = session.bbNet this.bbNet = session.bbNet
this.hasBigBlind = if (session.cgBigBlind != null) 1 else 0 this.hasBigBlind = if (session.cgBiggestBet != null) 1 else 0
this.estimatedHands = session.estimatedHands this.estimatedHands = session.estimatedHands
this.bbPer100Hands = this.bbPer100Hands =
session.bbNet / (session.numberOfHandsPerHour * session.hourlyDuration) * 100 session.bbNet / (session.numberOfHandsPerHour * session.hourlyDuration) * 100

@ -150,7 +150,7 @@ open class Result : RealmObject(), Filterable {
fun computeNumberOfRebuy() { fun computeNumberOfRebuy() {
this.session?.let { this.session?.let {
if (it.isCashGame()) { if (it.isCashGame()) {
it.cgBigBlind?.let { bb -> it.cgBiggestBet?.let { bb ->
if (bb > 0.0) { if (bb > 0.0) {
this.numberOfRebuy = (this.buyin ?: 0.0) / (bb * 100.0) this.numberOfRebuy = (this.buyin ?: 0.0) / (bb * 100.0)
} else { } else {

@ -32,18 +32,22 @@ import net.pokeranalytics.android.ui.adapter.UnmanagedRowRepresentableException
import net.pokeranalytics.android.ui.graph.Graph import net.pokeranalytics.android.ui.graph.Graph
import net.pokeranalytics.android.ui.view.* import net.pokeranalytics.android.ui.view.*
import net.pokeranalytics.android.ui.view.rows.SessionPropertiesRow import net.pokeranalytics.android.ui.view.rows.SessionPropertiesRow
import net.pokeranalytics.android.util.* import net.pokeranalytics.android.util.CrashLogging
import net.pokeranalytics.android.util.extensions.* import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.util.UserDefaults
import net.pokeranalytics.android.util.extensions.hourMinute
import net.pokeranalytics.android.util.extensions.shortDateTime
import net.pokeranalytics.android.util.extensions.toCurrency
import net.pokeranalytics.android.util.extensions.toMinutes
import java.text.DateFormat import java.text.DateFormat
import java.text.NumberFormat
import java.text.ParseException
import java.util.* import java.util.*
import java.util.Currency import java.util.Currency
typealias BB = Double typealias BB = Double
open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Timed, open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Timed,
TimeFilterable, Filterable, DatedBankrollGraphEntry { TimeFilterable, Filterable, DatedBankrollGraphEntry, StakesHolder {
enum class Type(val value: String) { enum class Type(val value: String) {
CASH_GAME("Cash Game"), CASH_GAME("Cash Game"),
@ -64,11 +68,6 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
companion object { companion object {
private val cbSeparator = ";"
private val cbAnte = "A="
private val cbBlinds = "B="
private val cbCode = "C="
fun newInstance(realm: Realm, isTournament: Boolean, bankroll: Bankroll? = null, managed: Boolean = true): Session { fun newInstance(realm: Realm, isTournament: Boolean, bankroll: Bankroll? = null, managed: Boolean = true): Session {
val session = Session() val session = Session()
session.result = Result() session.result = Result()
@ -302,17 +301,15 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
// Cash Game // Cash Game
// The small blind value // The small blind value
var cgSmallBlind: Double? = null var cgOldSmallBlind: Double? = null
set(value) { set(value) {
field = value field = value
// formatBlinds()
} }
// The big blind value // The big blind value
var cgBigBlind: Double? = null var cgOldBigBlind: Double? = null
set(value) { set(value) {
field = value field = value
// formatBlinds()
this.computeStats() this.computeStats()
this.result?.computeNumberOfRebuy() this.result?.computeNumberOfRebuy()
} }
@ -427,7 +424,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
*/ */
val bbNet: BB val bbNet: BB
get() { get() {
val bb = this.cgBigBlind val bb = this.cgBiggestBet
val result = this.result val result = this.result
return if (bb != null && result != null) { return if (bb != null && result != null) {
result.net / bb result.net / bb
@ -752,8 +749,8 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
copy.game = this.game copy.game = this.game
copy.limit = this.limit copy.limit = this.limit
copy.cgSmallBlind = this.cgSmallBlind copy.cgBiggestBet = this.cgBiggestBet
copy.cgBigBlind = this.cgBigBlind copy.cgAnte = this.cgAnte
copy.tournamentEntryFee = this.tournamentEntryFee copy.tournamentEntryFee = this.tournamentEntryFee
copy.tournamentFeatures = this.tournamentFeatures copy.tournamentFeatures = this.tournamentFeatures
copy.tournamentName = this.tournamentName copy.tournamentName = this.tournamentName
@ -798,8 +795,8 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
// } // }
// } // }
} else if (value == null) { } else if (value == null) {
cgSmallBlind = null this.cgBiggestBet = null
cgBigBlind = null this.cgAnte = null
} }
SessionPropertiesRow.BREAK_TIME -> { SessionPropertiesRow.BREAK_TIME -> {
this.breakDuration = (value as Double? ?: 0.0).toLong() * 60 * 1000 this.breakDuration = (value as Double? ?: 0.0).toLong() * 60 * 1000
@ -1081,45 +1078,71 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
/// Stakes /// Stakes
fun generateStakes() { // fun generateStakes() {
//
// if (this.cgAnte == null && this.cgAnte == null) {
// this.cgStakes = null
// return
// }
//
// val components = arrayListOf<String>()
//
// this.cgBlinds?.let { components.add("${cbBlinds}${it}") }
// this.cgAnte?.let { components.add("${cbAnte}${it.formatted}") }
//
// val code = this.bankroll?.currency?.code ?: UserDefaults.currency.currencyCode
// components.add("${cbCode}${code}")
//
// this.cgStakes = components.joinToString(cbSeparator)
// }
//
// fun defineHighestBet() {
// val bets = arrayListOf<Double>()
// this.cgAnte?.let { bets.add(it) }
// bets.addAll(this.blindValues)
// this.cgBiggestBet = bets.maxOrNull()
// }
if (this.cgAnte == null && this.cgAnte == null) { /// StakesHolder
this.cgStakes = null
return
}
val components = arrayListOf<String>() override val ante: Double?
get() { return this.cgAnte }
override val blinds: String?
get() { return this.cgBlinds }
this.cgBlinds?.let { components.add("${cbBlinds}${it}") } override val biggestBet: Double?
this.cgAnte?.let { components.add("${cbAnte}${it.formatted}") } get() { return this.cgBiggestBet }
val code = this.bankroll?.currency?.code ?: UserDefaults.currency.currencyCode override val stakes: String?
components.add("${cbCode}${code}") get() { return this.cgStakes }
this.cgStakes = components.joinToString(cbSeparator) // override val bankroll: Bankroll?
// get() { return this.bankroll }
override fun setHolderStakes(stakes: String?) {
this.cgStakes = stakes
} }
fun defineHighestBet() { override fun setHolderBiggestBet(biggestBet: Double?) {
val bets = arrayListOf<Double>() this.cgBiggestBet = biggestBet
this.cgAnte?.let { bets.add(it) }
bets.addAll(this.blindValues)
this.cgBiggestBet = bets.maxOrNull()
} }
private val blindValues: List<Double> //
get() { // private val blindValues: List<Double>
this.cgBlinds?.let { blinds -> // get() {
val blindsSplit = blinds.split(BLIND_SEPARATOR) // this.cgBlinds?.let { blinds ->
return blindsSplit.mapNotNull { // val blindsSplit = blinds.split(BLIND_SEPARATOR)
try { // return blindsSplit.mapNotNull {
NumberFormat.getInstance().parse(it)?.toDouble() // try {
} catch (e: ParseException) { // NumberFormat.getInstance().parse(it)?.toDouble()
null // } catch (e: ParseException) {
} // null
} // }
} // }
return listOf() // }
} // return listOf()
// }
} }

@ -15,10 +15,8 @@ import net.pokeranalytics.android.model.filter.Filterable
import net.pokeranalytics.android.model.handhistory.HandSetup import net.pokeranalytics.android.model.handhistory.HandSetup
import net.pokeranalytics.android.model.handhistory.Position import net.pokeranalytics.android.model.handhistory.Position
import net.pokeranalytics.android.model.handhistory.Street import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.interfaces.Deletable import net.pokeranalytics.android.model.interfaces.*
import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus import net.pokeranalytics.android.model.realm.Bankroll
import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.model.interfaces.TimeFilterable
import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.modules.handhistory.evaluator.EvaluatorBridge import net.pokeranalytics.android.ui.modules.handhistory.evaluator.EvaluatorBridge
import net.pokeranalytics.android.ui.modules.handhistory.model.ActionReadRow import net.pokeranalytics.android.ui.modules.handhistory.model.ActionReadRow
@ -35,7 +33,7 @@ import kotlin.math.max
data class PositionAmount(var position: Int, var amount: Double, var isAllin: Boolean) data class PositionAmount(var position: Int, var amount: Double, var isAllin: Boolean)
open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, TimeFilterable, open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, TimeFilterable,
CardHolder, Comparator<PositionAmount> { CardHolder, Comparator<PositionAmount>, StakesHolder {
@PrimaryKey @PrimaryKey
override var id = UUID.randomUUID().toString() override var id = UUID.randomUUID().toString()
@ -64,34 +62,67 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable,
/*** /***
* The small blind * The small blind
*/ */
var smallBlind: Double? = null var oldSmallBlind: Double? = null
set(value) { set(value) {
field = value field = value
if (this.bigBlind == null && value != null) { // if (this.bigBlind == null && value != null) {
this.bigBlind = value * 2 // this.bigBlind = value * 2
} // }
} }
/*** /***
* The big blind * The big blind
*/ */
var bigBlind: Double? = null var oldBigBlind: Double? = null
set(value) { set(value) {
field = value field = value
if (this.smallBlind == null && value != null) { // if (this.smallBlind == null && value != null) {
this.smallBlind = value / 2 // this.smallBlind = value / 2
} // }
} }
/***
* Big blind ante
*/
var bigBlindAnte: Boolean = false
/*** /***
* The ante * The ante
*/ */
var ante: Double = 0.0 override var ante: Double? = 0.0
set(value) {
field = value
this.generateStakes()
this.defineHighestBet()
}
/*** /***
* Big blind ante * The blinds
*/ */
var bigBlindAnte: Boolean = false override var blinds: String? = null
set(value) {
field = value
this.generateStakes()
this.defineHighestBet()
}
override var biggestBet: Double? = null
/***
* The coded stakes
*/
override var stakes: String? = null
override val bankroll: Bankroll?
get() { return this.session?.bankroll }
override fun setHolderStakes(stakes: String?) {
this.stakes = stakes
}
override fun setHolderBiggestBet(biggestBet: Double?) {
this.biggestBet = biggestBet
}
/*** /***
* Number of players in the hand * Number of players in the hand
@ -164,8 +195,8 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable,
this.playerSetups.removeAll(this.playerSetups) this.playerSetups.removeAll(this.playerSetups)
handSetup.tableSize?.let { this.numberOfPlayers = it } handSetup.tableSize?.let { this.numberOfPlayers = it }
handSetup.smallBlind?.let { this.smallBlind = it } handSetup.ante?.let { this.ante = it }
handSetup.bigBlind?.let { this.bigBlind = it } handSetup.blinds?.let { this.blinds = it }
this.session = handSetup.session this.session = handSetup.session
this.date = this.session?.handHistoryAutomaticDate ?: Date() this.date = this.session?.handHistoryAutomaticDate ?: Date()
@ -180,8 +211,17 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable,
this.actions.clear() this.actions.clear()
this.addAction(0, Action.Type.POST_SB, this.smallBlind) this.blindValues.forEachIndexed { index, blind ->
this.addAction(1, Action.Type.POST_BB, this.bigBlind) val action = when(index) {
0 -> Action.Type.POST_SB
1 -> Action.Type.POST_BB
else -> Action.Type.STRADDLE
}
this.addAction(index, action, blind)
}
// this.addAction(0, Action.Type.POST_SB, this.smallBlind)
// this.addAction(1, Action.Type.POST_BB, this.bigBlind)
// var lastStraddler: Int? = null // var lastStraddler: Int? = null
@ -237,9 +277,9 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable,
val anteSum: Double val anteSum: Double
get() { get() {
return if (bigBlindAnte) { return if (bigBlindAnte) {
this.bigBlind ?: 0.0 this.biggestBet ?: 0.0
} else { } else {
this.ante * this.numberOfPlayers (this.ante ?: 0.0) * this.numberOfPlayers
} }
} }
@ -303,14 +343,20 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable,
val players = "${this.numberOfPlayers} ${context.getString(R.string.players)}" val players = "${this.numberOfPlayers} ${context.getString(R.string.players)}"
val firstLineComponents = mutableListOf(this.date.fullDate(), players) val firstLineComponents = mutableListOf(this.date.fullDate(), players)
this.smallBlind?.let { sb -> this.blinds?.let { firstLineComponents.add(it) }
this.bigBlind?.let { bb ->
firstLineComponents.add("${sb.formatted}/${bb.formatted}") // this.smallBlind?.let { sb ->
// this.bigBlind?.let { bb ->
// firstLineComponents.add("${sb.formatted}/${bb.formatted}")
// }
// }
this.ante?.let {
if (it > 0.0) {
firstLineComponents.add("ante ${this.ante}")
} }
} }
if (this.ante > 0.0) {
firstLineComponents.add("ante ${this.ante}")
}
string = string.plus(firstLineComponents.joinToString(" - ")) string = string.plus(firstLineComponents.joinToString(" - "))
string = string.addLineReturn(2) string = string.addLineReturn(2)
@ -373,12 +419,12 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable,
fun anteForPosition(position: Position): Double { fun anteForPosition(position: Position): Double {
return if (this.bigBlindAnte) { return if (this.bigBlindAnte) {
if (position == Position.BB) { if (position == Position.BB) {
this.bigBlind ?: 0.0 this.biggestBet ?: 0.0
} else { } else {
0.0 0.0
} }
} else { } else {
this.ante this.ante ?: 0.0
} }
} }

@ -86,8 +86,8 @@ class FavoriteSessionFinder {
when (session.type) { when (session.type) {
Session.Type.CASH_GAME.ordinal -> { Session.Type.CASH_GAME.ordinal -> {
session.cgSmallBlind = fav.cgSmallBlind session.cgAnte = fav.cgAnte
session.cgBigBlind = fav.cgBigBlind session.cgBlinds = fav.cgBlinds
} }
Session.Type.TOURNAMENT.ordinal -> { Session.Type.TOURNAMENT.ordinal -> {
session.tournamentEntryFee = fav.tournamentEntryFee session.tournamentEntryFee = fav.tournamentEntryFee

@ -292,7 +292,7 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
private fun sessionsCSVExport() { private fun sessionsCSVExport() {
val sessions = getRealm().where(Session::class.java).findAll().sort("startDate") val sessions = getRealm().where(Session::class.java).findAll().sort("startDate")
val csv = ProductCSVDescriptors.pokerAnalyticsAndroid.toCSV(sessions) val csv = ProductCSVDescriptors.pokerAnalyticsAndroidSessions.toCSV(sessions)
this.shareCSV(csv, "Sessions") this.shareCSV(csv, "Sessions")
} }

@ -34,7 +34,12 @@ class BottomSheetStakesFragment : BottomSheetFragment() {
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
// binding.editText2.requestFocus()
// binding.editText2.setTextIsSelectable(true)
// binding.editText2.isFocusableInTouchMode = false
binding.editText2.requestFocus()
} }
/** /**
@ -60,7 +65,12 @@ class BottomSheetStakesFragment : BottomSheetFragment() {
// binding.editText2.setRawInputType(InputType.TYPE_CLASS_TEXT) //= InputType.TYPE_NULL // data[1].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES // binding.editText2.setRawInputType(InputType.TYPE_CLASS_TEXT) //= InputType.TYPE_NULL // data[1].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
// binding.editText2.inputType = InputType.TYPE_NULL // binding.editText2.inputType = InputType.TYPE_NULL
// binding.editText2.setTextIsSelectable(false)
// editText.setTextIsSelectable(true)
binding.editText2.setRawInputType(InputType.TYPE_CLASS_TEXT)
binding.editText2.setTextIsSelectable(true) binding.editText2.setTextIsSelectable(true)
binding.editText2.showSoftInputOnFocus = false
binding.editText2.onCreateInputConnection(EditorInfo())?.let { binding.editText2.onCreateInputConnection(EditorInfo())?.let {
binding.stakesKeyboard.inputConnection = it binding.stakesKeyboard.inputConnection = it
@ -93,16 +103,16 @@ class BottomSheetStakesFragment : BottomSheetFragment() {
this.model.secondStringValue = it?.toString() this.model.secondStringValue = it?.toString()
} }
binding.editText2.setOnEditorActionListener { _, actionId, _ -> // binding.editText2.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) { // if (actionId == EditorInfo.IME_ACTION_DONE) {
this.onRowValueChanged() // this.onRowValueChanged()
// this.delegate.onRowValueChanged(values, row) //// this.delegate.onRowValueChanged(values, row)
dismiss() // dismiss()
true // true
} else { // } else {
false // false
} // }
} // }
} }
} }

@ -192,7 +192,8 @@ class EditorAdapter(
"Edit Text not found for tag: $tag, class: $this" "Edit Text not found for tag: $tag, class: $this"
) )
// hides soft input view // hides soft input view,
// 22/06/22: does not seem useful as - I believe - manifest activity has android:windowSoftInputMode="stateAlwaysHidden"
editText.setTextIsSelectable(true) editText.setTextIsSelectable(true)
// Enabled // Enabled

@ -536,9 +536,9 @@ class ActionList(var listener: ActionListListener? = null) : ArrayList<ComputedA
*/ */
override fun blindsUpdated(type: Action.Type, amount: Double) { override fun blindsUpdated(type: Action.Type, amount: Double) {
when (type) { when (type) {
Action.Type.POST_SB -> this.handHistory.smallBlind = amount Action.Type.POST_SB -> this.handHistory.oldSmallBlind = amount
Action.Type.POST_BB -> { Action.Type.POST_BB -> {
this.handHistory.bigBlind = amount this.handHistory.oldBigBlind = amount
if (this.handHistory.bigBlindAnte) { if (this.handHistory.bigBlindAnte) {
this.updateBigBlindRemainingStack() this.updateBigBlindRemainingStack()
} }

@ -30,7 +30,6 @@ import net.pokeranalytics.android.util.CrashLogging
import net.pokeranalytics.android.util.extensions.findById import net.pokeranalytics.android.util.extensions.findById
import net.pokeranalytics.android.util.extensions.formatted import net.pokeranalytics.android.util.extensions.formatted
import timber.log.Timber import timber.log.Timber
import java.lang.Exception
import java.text.DecimalFormat import java.text.DecimalFormat
import java.text.ParseException import java.text.ParseException
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@ -261,8 +260,10 @@ class EditorViewModel : ViewModel(), RowRepresentableDataSource, CardCentralizer
rows.add(CustomizableRowRepresentable(customViewType = HandRowType.HEADER, resId = R.string.settings, value = "")) rows.add(CustomizableRowRepresentable(customViewType = HandRowType.HEADER, resId = R.string.settings, value = ""))
rows.add(HandRowType.PLAYER_NUMBER) rows.add(HandRowType.PLAYER_NUMBER)
if (this.handHistory.ante > 0) { this.handHistory.ante?.let {
rows.add(HandRowType.ANTE) if (it > 0) {
rows.add(HandRowType.ANTE)
}
} }
if (this.handHistory.bigBlindAnte) { if (this.handHistory.bigBlindAnte) {
@ -796,7 +797,7 @@ class EditorViewModel : ViewModel(), RowRepresentableDataSource, CardCentralizer
val string = when (row) { val string = when (row) {
HandRowType.PLAYER_NUMBER -> this.handHistory.numberOfPlayers.toString() HandRowType.PLAYER_NUMBER -> this.handHistory.numberOfPlayers.toString()
HandRowType.COMMENT -> this.handHistory.comment ?: context.getString(R.string.comment) HandRowType.COMMENT -> this.handHistory.comment ?: context.getString(R.string.comment)
HandRowType.ANTE -> this.handHistory.ante.formatted HandRowType.ANTE -> this.handHistory.ante?.formatted
HandRowType.BIG_BLIND_ANTE_READ -> context.getString(R.string.yes) HandRowType.BIG_BLIND_ANTE_READ -> context.getString(R.string.yes)
// HandRowType.HERO_POSITION -> context.getString(R.string.set_hero_position) // HandRowType.HERO_POSITION -> context.getString(R.string.set_hero_position)
// HandRowType.PLAYER_POSITION -> context.getString(R.string.set_position_details) // HandRowType.PLAYER_POSITION -> context.getString(R.string.set_position_details)

@ -26,7 +26,6 @@ import net.pokeranalytics.android.model.extensions.getState
import net.pokeranalytics.android.model.extensions.scheduleStopNotification import net.pokeranalytics.android.model.extensions.scheduleStopNotification
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.util.CrashLogging
import net.pokeranalytics.android.model.utils.FavoriteSessionFinder import net.pokeranalytics.android.model.utils.FavoriteSessionFinder
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
@ -38,6 +37,7 @@ import net.pokeranalytics.android.ui.modules.datalist.DataListActivity
import net.pokeranalytics.android.ui.modules.handhistory.HandHistoryActivity import net.pokeranalytics.android.ui.modules.handhistory.HandHistoryActivity
import net.pokeranalytics.android.ui.view.* import net.pokeranalytics.android.ui.view.*
import net.pokeranalytics.android.ui.view.rows.SessionPropertiesRow import net.pokeranalytics.android.ui.view.rows.SessionPropertiesRow
import net.pokeranalytics.android.util.CrashLogging
import net.pokeranalytics.android.util.Preferences import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.extensions.* import net.pokeranalytics.android.util.extensions.*
import timber.log.Timber import timber.log.Timber
@ -585,7 +585,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
) )
SessionPropertiesRow.BUY_IN -> row.editingDescriptors( SessionPropertiesRow.BUY_IN -> row.editingDescriptors(
mapOf( mapOf(
"bb" to session.cgBigBlind, "bb" to session.cgBiggestBet,
"fee" to session.tournamentEntryFee, "fee" to session.tournamentEntryFee,
"ratedBuyin" to session.result?.buyin "ratedBuyin" to session.result?.buyin
) )
@ -628,8 +628,8 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
) )
SessionPropertiesRow.TIPS -> row.editingDescriptors( SessionPropertiesRow.TIPS -> row.editingDescriptors(
mapOf( mapOf(
"sb" to session.cgSmallBlind?.round(), "sb" to session.cgBiggestBet?.round(),
"bb" to session.cgBigBlind?.round(), "bb" to session.cgBiggestBet?.round(),
"tips" to session.result?.tips "tips" to session.result?.tips
) )
) )

@ -90,9 +90,13 @@ class FakeDataManager {
if (isTournament) { if (isTournament) {
session.tournamentEntryFee = buyin session.tournamentEntryFee = buyin
} else { } else {
val bigBlind = arrayListOf(1.0, 2.0, 4.0).random()
session.cgBigBlind = bigBlind session.cgAnte = arrayListOf(1.0, null).random()
session.cgSmallBlind = bigBlind / 2.0 session.cgBlinds = arrayListOf("1/2", "2/5/10", "2").random()
// val bigBlind = arrayListOf(1.0, 2.0, 4.0).random()
// session.cgBigBlind = bigBlind
// session.cgSmallBlind = bigBlind / 2.0
} }
} }

@ -8,12 +8,14 @@ import net.pokeranalytics.android.model.TableSize
import net.pokeranalytics.android.model.TournamentType import net.pokeranalytics.android.model.TournamentType
import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.model.utils.DataUtils import net.pokeranalytics.android.model.utils.DataUtils
import net.pokeranalytics.android.util.BLIND_SEPARATOR
import net.pokeranalytics.android.util.extensions.count import net.pokeranalytics.android.util.extensions.count
import net.pokeranalytics.android.util.extensions.getOrCreate import net.pokeranalytics.android.util.extensions.getOrCreate
import net.pokeranalytics.android.util.extensions.setHourMinutes import net.pokeranalytics.android.util.extensions.setHourMinutes
import org.apache.commons.csv.CSVRecord import org.apache.commons.csv.CSVRecord
import timber.log.Timber import timber.log.Timber
import java.text.DateFormat import java.text.DateFormat
import java.text.NumberFormat
import java.text.ParseException import java.text.ParseException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -57,6 +59,9 @@ abstract class PACSVDescriptor<T : Identifiable>(source: DataSource,
var stackingIn: Double? = null var stackingIn: Double? = null
var stackingOut: Double? = null var stackingOut: Double? = null
var sb: Double? = null
var bb: Double? = null
this.fields.forEach { field -> this.fields.forEach { field ->
this.fieldMapping[field]?.let { index -> this.fieldMapping[field]?.let { index ->
@ -169,38 +174,40 @@ abstract class PACSVDescriptor<T : Identifiable>(source: DataSource,
is SessionField.Bankroll -> bankrollName = value is SessionField.Bankroll -> bankrollName = value
is SessionField.LimitType -> session.limit = Limit.getInstance(value)?.ordinal is SessionField.LimitType -> session.limit = Limit.getInstance(value)?.ordinal
is SessionField.Comment -> session.comment = value is SessionField.Comment -> session.comment = value
is SessionField.Blind -> { // 1/2 is SessionField.Blind, is SessionField.Blinds -> { // 1/2
val blinds = field.parse(value) session.cgBlinds = value
session.cgSmallBlind = blinds?.first
session.cgBigBlind = blinds?.second // val blinds = field.parse(value)
// session.cgSmallBlind = blinds?.first
// session.cgBigBlind = blinds?.second
} }
is SessionField.SmallBlind -> { is SessionField.SmallBlind -> {
val sb = field.parse(value) sb = field.parse(value)
if (sb != null && sb > 0.0) { // if (sb != null && sb > 0.0) {
session.cgSmallBlind = sb // session.cgSmallBlind = sb
} else {} // } else {}
} }
is SessionField.BigBlind -> { is SessionField.BigBlind -> {
val bb = field.parse(value) bb = field.parse(value)
if (bb != null && bb > 0.0) { // if (bb != null && bb > 0.0) {
session.cgBigBlind = bb // session.cgBigBlind = bb
} else {} // } else {}
}
is SessionField.Blinds -> {
val blinds = value.split("/")
when (blinds.size) {
0 -> {}
1 -> {
session.cgBigBlind = field.parse(blinds.first())
}
else -> {
session.cgSmallBlind = field.parse(blinds[blinds.size - 2])
session.cgBigBlind = field.parse(blinds.last())
}
}
} }
// is SessionField.Blinds -> {
// val blinds = value.split("/")
// when (blinds.size) {
// 0 -> {}
// 1 -> {
// session.cgBigBlind = field.parse(blinds.first())
// }
// else -> {
// session.cgSmallBlind = field.parse(blinds[blinds.size - 2])
// session.cgBigBlind = field.parse(blinds.last())
// }
// }
// }
is SessionField.Ante -> { is SessionField.Ante -> {
// unmanaged atm session.cgAnte = field.parse(value)
} }
is SessionField.TableSize -> session.tableSize = TableSize.valueForLabel(value) is SessionField.TableSize -> session.tableSize = TableSize.valueForLabel(value)
is SessionField.TournamentPosition -> session.result?.tournamentFinalPosition = is SessionField.TournamentPosition -> session.result?.tournamentFinalPosition =
@ -256,6 +263,11 @@ abstract class PACSVDescriptor<T : Identifiable>(source: DataSource,
} }
val blinds = arrayListOf(sb, bb).filterNotNull()
if (blinds.isNotEmpty()) {
session.cgBlinds = blinds.joinToString(BLIND_SEPARATOR) { NumberFormat.getInstance().format(it) }
}
val bankroll = Bankroll.getOrCreate(realm, bankrollName, isLive, currencyCode, currencyRate) val bankroll = Bankroll.getOrCreate(realm, bankrollName, isLive, currencyCode, currencyRate)
session.bankroll = bankroll session.bankroll = bankroll

@ -18,7 +18,8 @@ class ProductCSVDescriptors {
runGoodTournaments, runGoodTournaments,
pokerAnalyticsiOS, pokerAnalyticsiOS,
pokerAnalytics6iOS, pokerAnalytics6iOS,
pokerAnalyticsAndroid, pokerAnalyticsAndroidSessions,
pokerAnalyticsAndroid6Sessions,
pokerAnalyticsAndroidTransactions pokerAnalyticsAndroidTransactions
) )
@ -239,7 +240,7 @@ class ProductCSVDescriptors {
) )
} }
val pokerAnalyticsAndroid: SessionCSVDescriptor val pokerAnalyticsAndroidSessions: SessionCSVDescriptor
get() { get() {
return SessionCSVDescriptor( return SessionCSVDescriptor(
DataSource.POKER_ANALYTICS, DataSource.POKER_ANALYTICS,
@ -273,6 +274,42 @@ class ProductCSVDescriptors {
SessionField.Comment("Comment") SessionField.Comment("Comment")
) )
} }
val pokerAnalyticsAndroid6Sessions: SessionCSVDescriptor
get() {
return SessionCSVDescriptor(
DataSource.POKER_ANALYTICS,
true,
SessionField.Start("Start Date", dateFormat = "MM/dd/yy HH:mm:ss"),
SessionField.End("End Date", dateFormat = "MM/dd/yy HH:mm:ss"),
SessionField.Break("Break"),
SessionField.SessionType("Type"),
SessionField.Live("Live"),
SessionField.NumberOfTables("Tables"),
SessionField.Buyin("Buyin"),
SessionField.CashedOut("Cashed Out"),
SessionField.NetResult("Online Net"),
SessionField.Tips("Tips"),
SessionField.HandsCount("Hands Count"),
SessionField.LimitType("Limit"),
SessionField.Game("Game"),
SessionField.TableSize("Table Size"),
SessionField.Location("Location"),
SessionField.Bankroll("Bankroll"),
SessionField.CurrencyCode("Currency Code"),
SessionField.CurrencyRate("Currency Rate"),
SessionField.Ante("Antes"),
SessionField.Blinds("Blinds"),
SessionField.TournamentTypeName("Tournament Type"),
SessionField.TournamentName("Tournament Name"),
SessionField.TournamentEntryFee("Entry fee"),
SessionField.TournamentNumberOfPlayers("Number of players"),
SessionField.TournamentFeatures("Tournament Features"),
SessionField.TournamentPosition("Position"),
SessionField.Comment("Comment")
)
}
} }
} }

@ -7,7 +7,6 @@ import net.pokeranalytics.android.model.TournamentType
import net.pokeranalytics.android.model.realm.CustomField import net.pokeranalytics.android.model.realm.CustomField
import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Session
import org.apache.commons.csv.CSVRecord import org.apache.commons.csv.CSVRecord
import timber.log.Timber
/** /**
* A SessionCSVDescriptor is a CSVDescriptor specialized in parsing Session objects * A SessionCSVDescriptor is a CSVDescriptor specialized in parsing Session objects
@ -63,8 +62,10 @@ class SessionCSVDescriptor(source: DataSource, isTournament: Boolean?, vararg el
is SessionField.Bankroll -> data.bankroll?.name is SessionField.Bankroll -> data.bankroll?.name
is SessionField.CurrencyCode -> data.bankroll?.currency?.code is SessionField.CurrencyCode -> data.bankroll?.currency?.code
is SessionField.CurrencyRate -> field.format(data.bankroll?.currency?.rate) is SessionField.CurrencyRate -> field.format(data.bankroll?.currency?.rate)
is SessionField.SmallBlind -> field.format(data.cgSmallBlind) // is SessionField.SmallBlind -> field.format(data.cgSmallBlind)
is SessionField.BigBlind -> field.format(data.cgBigBlind) // is SessionField.BigBlind -> field.format(data.cgBigBlind)
is SessionField.Blinds -> data.cgBlinds
is SessionField.Ante -> field.format(data.cgAnte)
is SessionField.TournamentType -> field.format(data.tournamentType) is SessionField.TournamentType -> field.format(data.tournamentType)
is SessionField.TournamentTypeName -> { is SessionField.TournamentTypeName -> {
data.tournamentType?.let { tt -> data.tournamentType?.let { tt ->

@ -42,7 +42,6 @@
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:gravity="center" android:gravity="center"
android:imeOptions="actionDone"
android:lines="1" android:lines="1"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"

Loading…
Cancel
Save