Adds ability to change the way to enter results for online sessions

kmm
Laurent 5 years ago
parent 1322952b47
commit 141a0f49d7
  1. 15
      app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt
  2. 331
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  3. 115
      app/src/main/java/net/pokeranalytics/android/ui/modules/data/BankrollDataFragment.kt
  4. 6
      app/src/main/java/net/pokeranalytics/android/ui/modules/data/DataManagerFragment.kt
  5. 1
      app/src/main/java/net/pokeranalytics/android/ui/modules/data/EditableDataFragment.kt
  6. 255
      app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt
  7. 14
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/BankrollRow.kt
  8. 15
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SessionRow.kt
  9. 2
      app/src/main/java/net/pokeranalytics/android/ui/viewmodel/DataManagerViewModel.kt
  10. 24
      app/src/main/java/net/pokeranalytics/android/util/Preferences.kt

@ -16,9 +16,15 @@ 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.Preferences
import net.pokeranalytics.android.util.UserDefaults
import java.util.*
enum class ResultCaptureType {
BUYIN_CASHEDOUT,
NET_RESULT
}
open class Bankroll : RealmObject(), NameManageable, RowRepresentable {
@PrimaryKey
@ -100,6 +106,15 @@ open class Bankroll : RealmObject(), NameManageable, RowRepresentable {
}
}
fun resultCaptureType(context: Context): ResultCaptureType {
return Preferences.getResultCaptureType(this, context) ?: run {
when (this.live) {
true -> ResultCaptureType.BUYIN_CASHEDOUT
else -> ResultCaptureType.NET_RESULT
}
}
}
companion object {
fun getOrCreate(realm: Realm, name: String, live: Boolean = true, currencyCode: String? = null, currencyRate: Double? = null) : Bankroll {

@ -13,7 +13,6 @@ import io.realm.annotations.LinkingObjects
import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.StatFormattingException
import net.pokeranalytics.android.exceptions.ModelException
@ -30,12 +29,9 @@ import net.pokeranalytics.android.model.filter.QueryCondition.*
import net.pokeranalytics.android.model.interfaces.*
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
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.view.*
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRow
import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow
import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.TextFormat
@ -44,11 +40,10 @@ import net.pokeranalytics.android.util.extensions.*
import java.text.DateFormat
import java.util.*
import java.util.Currency
import kotlin.collections.ArrayList
typealias BB = Double
open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDataSource, RowRepresentable, Timed,
open class Session : RealmObject(), Savable, Editable, RowRepresentable, Timed,
TimeFilterable, Filterable, DatedBankrollGraphEntry {
enum class Type(val value: String) {
@ -252,7 +247,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
override var pauseDate: Date? = null
set(value) {
field = value
this.updateRowRepresentation()
// this.updateRowRepresentation()
}
// The session set containing the sessions, which can contain multiple endedSessions
@ -266,7 +261,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
set(value) {
field = value
this.formatBlinds()
this.updateRowRepresentation()
// this.updateRowRepresentation()
}
// The limit type: NL, PL...
@ -353,7 +348,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
} else if (this.sessionSet != null) {
SessionSetManager.removeFromTimeline(this)
}
this.updateRowRepresentation()
// this.updateRowRepresentation()
}
/**
@ -465,7 +460,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
return playerHandsPerHour / tableSize.toDouble()
}
private val hourlyRate: Double
val hourlyRate: Double
get() {
this.result?.let { result ->
return result.net / this.hourlyDuration
@ -706,273 +701,10 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
@Ignore
override val viewType: Int = RowViewType.ROW_SESSION.ordinal
// Override to surcharge custom field viewType
override fun viewTypeForPosition(position: Int): Int {
rowRepresentationForCurrentState[position].let {
if (it is CustomField) {
return RowViewType.TITLE_VALUE.ordinal
}
}
return super.viewTypeForPosition(position)
}
override fun getDisplayName(context: Context): String {
return "Session ${this.creationDate}"
}
@Ignore
private var rowRepresentationForCurrentState: List<RowRepresentable> = mutableListOf()
private fun updatedRowRepresentationForCurrentState(): List<RowRepresentable> {
val rows = ArrayList<RowRepresentable>()
// Headers
when (getState()) {
SessionState.STARTED -> {
rows.add(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT_BIG,
title = getFormattedDuration(),
valueTextFormat = ComputedStat(Stat.NET_RESULT, result?.net ?: 0.0, currency = currency).textFormat
)
)
rows.add(SeparatorRow())
}
SessionState.PAUSED -> {
rows.add(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT_BIG,
resId = R.string.pause,
valueTextFormat = ComputedStat(Stat.NET_RESULT, result?.net ?: 0.0, currency = currency).textFormat
)
)
rows.add(SeparatorRow())
}
SessionState.FINISHED -> {
rows.add(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT_BIG,
title = getFormattedDuration(),
valueTextFormat = ComputedStat(Stat.NET_RESULT, result?.net ?: 0.0, currency = currency).textFormat
)
)
rows.add(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT,
resId = R.string.hour_rate_without_pauses,
valueTextFormat = ComputedStat(Stat.HOURLY_RATE, this.hourlyRate, currency = currency).textFormat
)
)
// if (!isTournament()) {
// rows.add(
// CustomizableRowRepresentable(
// RowViewType.HEADER_TITLE_VALUE,
// resId = R.string.bankroll_variation,
// computedStat = ComputedStat(Stat.HOURLY_RATE, 0.0, CurrencyUtils.getCurrency(bankroll))
// )
// )
// }
rows.add(SeparatorRow())
}
else -> {
}
}
// Rows
rows.addAll(SessionRow.getRows(this))
// Add custom fields
realm?.let {
rows.add(SeparatorRow())
rows.addAll(it.sorted<CustomField>())
}
return rows
}
fun updateRowRepresentation() {
this.rowRepresentationForCurrentState = this.updatedRowRepresentationForCurrentState()
}
override fun adapterRows(): List<RowRepresentable>? {
return this.rowRepresentationForCurrentState
}
override fun boolForRow(row: RowRepresentable): Boolean {
return false
}
override fun charSequenceForRow(row: RowRepresentable, context: Context): String {
return when (row) {
SessionRow.BANKROLL -> bankroll?.name ?: NULL_TEXT
SessionRow.BLINDS -> getFormattedBlinds()
SessionRow.BREAK_TIME -> if (this.breakDuration > 0.0) this.breakDuration.toMinutes() else NULL_TEXT
SessionRow.BUY_IN -> this.result?.buyin?.toCurrency(currency) ?: NULL_TEXT
SessionRow.CASHED_OUT, SessionRow.PRIZE -> this.result?.cashout?.toCurrency(currency) ?: NULL_TEXT
SessionRow.NET_RESULT -> this.result?.netResult?.toCurrency(currency) ?: NULL_TEXT
SessionRow.COMMENT -> if (this.comment.isNotEmpty()) this.comment else NULL_TEXT
SessionRow.END_DATE -> this.endDate?.shortDateTime() ?: NULL_TEXT
SessionRow.GAME -> getFormattedGame()
SessionRow.INITIAL_BUY_IN -> tournamentEntryFee?.toCurrency(currency) ?: NULL_TEXT
SessionRow.LOCATION -> location?.name ?: NULL_TEXT
SessionRow.PLAYERS -> tournamentNumberOfPlayers?.toString() ?: NULL_TEXT
SessionRow.POSITION -> result?.tournamentFinalPosition?.toString() ?: NULL_TEXT
SessionRow.START_DATE -> this.startDate?.shortDateTime() ?: NULL_TEXT
SessionRow.TABLE_SIZE -> this.tableSize?.let { TableSize(it).localizedTitle(context) } ?: NULL_TEXT
SessionRow.TIPS -> result?.tips?.toCurrency(currency) ?: NULL_TEXT
SessionRow.TOURNAMENT_TYPE -> {
this.tournamentType?.let {
TournamentType.values()[it].localizedTitle(context)
} ?: run {
NULL_TEXT
}
}
SessionRow.TOURNAMENT_FEATURE -> {
if (tournamentFeatures.size > 2) {
"${tournamentFeatures.subList(0, 2).joinToString {
it.name
}}, ..."
} else if (tournamentFeatures.size > 0) {
tournamentFeatures.joinToString {
it.name
}
} else {
NULL_TEXT
}
}
SessionRow.TOURNAMENT_NAME -> tournamentName?.name ?: NULL_TEXT
SessionRow.HANDS -> this.handHistories?.size.toString()
is CustomField -> {
customFieldEntries.find { it.customField?.id == row.id }?.let { customFieldEntry ->
return customFieldEntry.getFormattedValue(currency)
}
return NULL_TEXT
}
else -> throw UnmanagedRowRepresentableException("Unmanaged row = $row")
}
}
override fun actionIconForRow(row: RowRepresentable): Int? {
return when (row) {
SessionRow.START_DATE, SessionRow.END_DATE -> {
R.drawable.ic_close
}
else -> null
}
}
override fun editDescriptors(row: RowRepresentable): List<RowRepresentableEditDescriptor>? {
return when (row) {
SessionRow.BANKROLL -> row.editingDescriptors(
mapOf(
"defaultValue" to this.bankroll,
"data" to realm.sorted<Bankroll>() // LiveData.Bankroll.items(realm)
)
)
SessionRow.GAME -> row.editingDescriptors(
mapOf(
"limit" to this.limit,
"defaultValue" to this.game,
"data" to realm.sorted<Game>() //LiveData.Game.items(realm)
)
)
SessionRow.LOCATION -> row.editingDescriptors(
mapOf(
"defaultValue" to this.location,
"data" to realm.sorted<Location>() // LiveData.Location.items(realm)
)
)
SessionRow.TOURNAMENT_FEATURE -> row.editingDescriptors(
mapOf(
"defaultValue" to this.tournamentFeatures,
"data" to realm.sorted<TournamentFeature>() //LiveData.TournamentFeature.items(realm)
)
)
SessionRow.TOURNAMENT_NAME -> row.editingDescriptors(
mapOf(
"defaultValue" to this.tournamentName,
"data" to realm.sorted<TournamentName>() //LiveData.TournamentName.items(realm)
)
)
SessionRow.TOURNAMENT_TYPE -> row.editingDescriptors(
mapOf(
"defaultValue" to this.tournamentType
)
)
SessionRow.TABLE_SIZE -> row.editingDescriptors(
mapOf(
"defaultValue" to this.tableSize
)
)
SessionRow.BLINDS -> row.editingDescriptors(
mapOf(
"sb" to cgSmallBlind?.round(),
"bb" to cgBigBlind?.round()
)
)
SessionRow.BUY_IN -> row.editingDescriptors(
mapOf(
"bb" to cgBigBlind,
"fee" to this.tournamentEntryFee,
"ratedBuyin" to result?.buyin
)
)
SessionRow.BREAK_TIME -> row.editingDescriptors(mapOf())
SessionRow.CASHED_OUT, SessionRow.PRIZE -> row.editingDescriptors(
mapOf(
"defaultValue" to result?.cashout
)
)
SessionRow.NET_RESULT -> row.editingDescriptors(
mapOf(
"defaultValue" to result?.netResult
)
)
SessionRow.COMMENT -> row.editingDescriptors(
mapOf(
"defaultValue" to this.comment
)
)
SessionRow.INITIAL_BUY_IN -> row.editingDescriptors(
mapOf(
"defaultValue" to this.tournamentEntryFee
)
)
SessionRow.PLAYERS -> row.editingDescriptors(
mapOf(
"defaultValue" to this.tournamentNumberOfPlayers
)
)
SessionRow.POSITION -> row.editingDescriptors(
mapOf(
"defaultValue" to this.result?.tournamentFinalPosition
)
)
SessionRow.TIPS -> row.editingDescriptors(
mapOf(
"sb" to cgSmallBlind?.round(),
"bb" to cgBigBlind?.round(),
"tips" to result?.tips
)
)
is CustomField -> {
row.editingDescriptors(
when (row.type) {
CustomField.Type.LIST.uniqueIdentifier -> mapOf(
"defaultValue" to customFieldEntries.find { it.customField?.id == row.id }?.value,
"data" to row.entries
)
else -> mapOf(
"defaultValue" to customFieldEntries.find { it.customField?.id == row.id }?.numericValue
)
}
)
}
else -> null
}
}
override fun updateValue(value: Any?, row: RowRepresentable) {
when (row) {
@ -1005,7 +737,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
SessionRow.BUY_IN -> {
val localResult = getOrCreateResult()
localResult.buyin = value as Double?
this.updateRowRepresentation()
// this.updateRowRepresentation()
}
SessionRow.CASHED_OUT, SessionRow.PRIZE -> {
val localResult = getOrCreateResult()
@ -1210,4 +942,55 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
@Ignore
override val realmObjectClass: Class<out Identifiable> = Session::class.java
fun charSequenceForRow(row: RowRepresentable, context: Context): String {
return when (row) {
SessionRow.BANKROLL -> bankroll?.name ?: NULL_TEXT
SessionRow.BLINDS -> getFormattedBlinds()
SessionRow.BREAK_TIME -> if (this.breakDuration > 0.0) this.breakDuration.toMinutes() else NULL_TEXT
SessionRow.BUY_IN -> this.result?.buyin?.toCurrency(currency) ?: NULL_TEXT
SessionRow.CASHED_OUT, SessionRow.PRIZE -> this.result?.cashout?.toCurrency(currency) ?: NULL_TEXT
SessionRow.NET_RESULT -> this.result?.netResult?.toCurrency(currency) ?: NULL_TEXT
SessionRow.COMMENT -> if (this.comment.isNotEmpty()) this.comment else NULL_TEXT
SessionRow.END_DATE -> this.endDate?.shortDateTime() ?: NULL_TEXT
SessionRow.GAME -> getFormattedGame()
SessionRow.INITIAL_BUY_IN -> tournamentEntryFee?.toCurrency(currency) ?: NULL_TEXT
SessionRow.LOCATION -> location?.name ?: NULL_TEXT
SessionRow.PLAYERS -> tournamentNumberOfPlayers?.toString() ?: NULL_TEXT
SessionRow.POSITION -> result?.tournamentFinalPosition?.toString() ?: NULL_TEXT
SessionRow.START_DATE -> this.startDate?.shortDateTime() ?: NULL_TEXT
SessionRow.TABLE_SIZE -> this.tableSize?.let { TableSize(it).localizedTitle(context) } ?: NULL_TEXT
SessionRow.TIPS -> result?.tips?.toCurrency(currency) ?: NULL_TEXT
SessionRow.TOURNAMENT_TYPE -> {
this.tournamentType?.let {
TournamentType.values()[it].localizedTitle(context)
} ?: run {
NULL_TEXT
}
}
SessionRow.TOURNAMENT_FEATURE -> {
if (tournamentFeatures.size > 2) {
"${tournamentFeatures.subList(0, 2).joinToString {
it.name
}}, ..."
} else if (tournamentFeatures.size > 0) {
tournamentFeatures.joinToString {
it.name
}
} else {
NULL_TEXT
}
}
SessionRow.TOURNAMENT_NAME -> tournamentName?.name ?: NULL_TEXT
SessionRow.HANDS -> this.handHistories?.size.toString()
is CustomField -> {
customFieldEntries.find { it.customField?.id == row.id }?.let { customFieldEntry ->
return customFieldEntry.getFormattedValue(currency)
}
return NULL_TEXT
}
else -> throw UnmanagedRowRepresentableException("Unmanaged row = $row")
}
}
}

@ -5,9 +5,12 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModelProvider
import net.pokeranalytics.android.R
import net.pokeranalytics.android.api.FreeConverterApi
import net.pokeranalytics.android.model.realm.Bankroll
import net.pokeranalytics.android.model.realm.ResultCaptureType
import net.pokeranalytics.android.ui.activity.CurrenciesActivity
import net.pokeranalytics.android.ui.activity.components.RequestCode
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
@ -19,24 +22,37 @@ import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.BankrollRow
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow
import net.pokeranalytics.android.ui.viewmodel.DataManagerViewModel
import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.UserDefaults
import net.pokeranalytics.android.util.extensions.toCurrency
import net.pokeranalytics.android.util.extensions.toRate
import java.util.*
class BankrollDataViewModel: DataManagerViewModel() {
var selectedCaptureType: MutableLiveData<ResultCaptureType> = MutableLiveData(ResultCaptureType.BUYIN_CASHEDOUT)
}
/**
* Custom EditableDataFragment to manage the Bankroll data
*/
class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataSource {
private val bankrollModel: BankrollDataViewModel by lazy {
ViewModelProvider(this).get(BankrollDataViewModel::class.java)
}
// Return the item as a Bankroll object
private val bankroll: Bankroll
get() {
return this.model.item as Bankroll
}
override val modelClass: Class<out DataManagerViewModel> = BankrollDataViewModel::class.java
private lateinit var defaultCurrency: Currency
private val rows = ArrayList<RowRepresentable>()
private var isRefreshingRate = false
@ -55,6 +71,7 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
shouldOpenKeyboard = false
initData()
initUI()
refreshRows()
updateAdapterUI()
}
@ -72,6 +89,33 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
}
}
/**
* Init data
*/
override fun initData() {
super.initData()
defaultCurrency = UserDefaults.currency
if (!deleteButtonShouldAppear) {
bankroll.currency = net.pokeranalytics.android.model.realm.Currency()
bankroll.currency?.code = defaultCurrency.currencyCode
bankroll.currency?.rate = 1.0
}
Preferences.getResultCaptureType(this.bankroll, requireContext())?.let {
this.bankrollModel.selectedCaptureType.value = it
}
}
private fun initUI() {
this.bankrollModel.selectedCaptureType.observeForever {
rowRepresentableAdapter.notifyDataSetChanged()
}
}
override fun getDataSource(): RowRepresentableDataSource {
return this
}
@ -80,11 +124,15 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
return rows
}
override fun charSequenceForRow(
row: RowRepresentable,
context: Context,
tag: Int
): CharSequence {
override fun isSelected(position: Int, row: RowRepresentable, tag: Int): Boolean {
return when (row) {
BankrollRow.CAPTURE_BUYIN_CASHEDOUT -> this.bankrollModel.selectedCaptureType.value == ResultCaptureType.BUYIN_CASHEDOUT
BankrollRow.CAPTURE_NET_RESULT -> this.bankrollModel.selectedCaptureType.value == ResultCaptureType.NET_RESULT
else -> false
}
}
override fun charSequenceForRow(row: RowRepresentable, context: Context, tag: Int): CharSequence {
return when (row) {
SimpleRow.NAME -> if (bankroll.name.isNotEmpty()) bankroll.name else NULL_TEXT
BankrollRow.CURRENCY -> {
@ -137,6 +185,8 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
RequestCode.CURRENCY.value
)
BankrollRow.REFRESH_RATE -> refreshRate()
BankrollRow.CAPTURE_BUYIN_CASHEDOUT -> this.bankrollModel.selectedCaptureType.value = ResultCaptureType.BUYIN_CASHEDOUT
BankrollRow.CAPTURE_NET_RESULT -> this.bankrollModel.selectedCaptureType.value = ResultCaptureType.NET_RESULT
else -> super.onRowSelected(position, row, tag)
}
}
@ -154,21 +204,6 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
updateAdapterUI()
}
/**
* Init data
*/
override fun initData() {
super.initData()
defaultCurrency = UserDefaults.currency
if (!deleteButtonShouldAppear) {
bankroll.currency = net.pokeranalytics.android.model.realm.Currency()
bankroll.currency?.code = defaultCurrency.currencyCode
bankroll.currency?.rate = 1.0
}
}
/**
* Refresh rows
*/
@ -184,6 +219,12 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
rows.add(BankrollRow.RATE)
rows.add(BankrollRow.REFRESH_RATE)
}
if (!this.bankroll.live) {
rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.bankroll_capture_method))
rows.add(BankrollRow.CAPTURE_BUYIN_CASHEDOUT)
rows.add(BankrollRow.CAPTURE_NET_RESULT)
}
}
/**
@ -221,34 +262,16 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
rowRepresentableAdapter.refreshRow(BankrollRow.REFRESH_RATE)
}
// val call = CurrencyConverterApi.getApi(requireContext())?.convert(currenciesConverterValue)
// call?.enqueue(object : retrofit2.Callback<Map<String, CurrencyConverterValue>> {
//
// override fun onResponse(call: Call<Map<String, CurrencyConverterValue>>, response: Response<Map<String, CurrencyConverterValue>>) {
// response.body()?.let {
// it[currenciesConverterValue]?.value?.let { rate ->
// Timber.d("rate found = $rate")
// onRowValueChanged(rate, BankrollRow.RATE)
// } ?: run {
// Timber.d("no rate for $currenciesConverterValue")
// }
// } ?: run {
// Timber.d("onResponse> no body in ${response}")
// }
//
// isRefreshingRate = false
// rowRepresentableAdapter.refreshRow(BankrollRow.REFRESH_RATE)
// }
//
// override fun onFailure(call: Call<Map<String, CurrencyConverterValue>>, t: Throwable) {
// Timber.d("api call failed: ${t.message}")
// isRefreshingRate = false
// rowRepresentableAdapter.refreshRow(BankrollRow.REFRESH_RATE)
// }
// })
this.isRefreshingRate = true
this.rowRepresentableAdapter.refreshRow(BankrollRow.REFRESH_RATE)
}
override fun willSaveData() {
super.willSaveData()
this.bankrollModel.selectedCaptureType.value?.let {
Preferences.setResultCaptureType(this.bankroll, it, requireContext())
}
}
}

@ -19,10 +19,12 @@ import net.pokeranalytics.android.ui.viewmodel.DataManagerViewModel
open class DataManagerFragment : RealmFragment() {
protected val model: DataManagerViewModel by lazy {
ViewModelProvider(this).get(DataManagerViewModel::class.java)
protected open val model: DataManagerViewModel by lazy {
ViewModelProvider(this).get(modelClass)
}
open val modelClass: Class<out DataManagerViewModel> = DataManagerViewModel::class.java
// lateinit var item: Deletable
// protected lateinit var liveDataType: LiveData
// protected var primaryKey: String? = null

@ -15,7 +15,6 @@ import net.pokeranalytics.android.model.interfaces.NameManageable
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.bottomsheet.BottomSheetFragment
import net.pokeranalytics.android.ui.view.RowRepresentable

@ -1,5 +1,6 @@
package net.pokeranalytics.android.ui.modules.session
import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.view.*
@ -10,11 +11,14 @@ import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DiffUtil
import com.crashlytics.android.Crashlytics
import io.realm.annotations.Ignore
import kotlinx.android.synthetic.main.fragment_session.*
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
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.BankrollReportManager
import net.pokeranalytics.android.calculus.optimalduration.CashGameOptimalDurationCalculator
import net.pokeranalytics.android.exceptions.PAIllegalStateException
@ -24,28 +28,26 @@ import net.pokeranalytics.android.model.extensions.cancelStopNotification
import net.pokeranalytics.android.model.extensions.getState
import net.pokeranalytics.android.model.extensions.scheduleStopNotification
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.model.realm.Location
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.model.utils.FavoriteSessionFinder
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.RealmFragment
import net.pokeranalytics.android.ui.helpers.DateTimePickerManager
import net.pokeranalytics.android.ui.modules.data.EditableDataActivity
import net.pokeranalytics.android.ui.modules.datalist.DataListActivity
import net.pokeranalytics.android.ui.modules.handhistory.HandHistoryActivity
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableDiffCallback
import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager
import net.pokeranalytics.android.ui.view.*
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRow
import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow
import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.extensions.findById
import net.pokeranalytics.android.util.extensions.formattedHourlyDuration
import net.pokeranalytics.android.util.extensions.getNextMinuteInMilliseconds
import net.pokeranalytics.android.util.extensions.*
import timber.log.Timber
import java.util.*
class SessionFragment : RealmFragment(), RowRepresentableDelegate {
class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepresentableDataSource {
private lateinit var viewModel: SessionViewModel
@ -114,7 +116,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate {
toolbar.title = if (currentSession.isTournament()) getString(R.string.tournament) else getString(R.string.cash_game)
collapsingToolbar.title = toolbar.title
sessionAdapter = RowRepresentableAdapter(currentSession, this)
sessionAdapter = RowRepresentableAdapter(this, this)
recyclerView.adapter = sessionAdapter
updateSessionUI(true)
@ -216,7 +218,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate {
val session = this.currentSession
val data = session.editDescriptors(row)
val data = this.editDescriptors(row)
when (row) {
SessionRow.START_DATE -> DateTimePickerManager.create(requireContext(), row, this, session.startDate)
SessionRow.END_DATE -> {
@ -270,7 +272,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate {
*/
private fun updateSessionUI(firstDisplay: Boolean = false) {
this.currentSession.updateRowRepresentation()
this.updateRowRepresentation()
handler.removeCallbacksAndMessages(null)
@ -340,7 +342,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate {
* Update adapter UI
*/
private fun updateAdapterUI() {
currentSession.adapterRows()?.let {
this.adapterRows()?.let {
val diffResult = DiffUtil.calculateDiff(RowRepresentableDiffCallback(it, oldRows))
sessionAdapter.updateRows(diffResult)
@ -460,4 +462,231 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate {
}
}
// Static Data Source
// Override to surcharge custom field viewType
override fun viewTypeForPosition(position: Int): Int {
rowRepresentationForCurrentState[position].let {
if (it is CustomField) {
return RowViewType.TITLE_VALUE.ordinal
}
}
return super.viewTypeForPosition(position)
}
@Ignore
private var rowRepresentationForCurrentState: List<RowRepresentable> = mutableListOf()
private fun updatedRowRepresentationForCurrentState(context: Context): List<RowRepresentable> {
val rows = ArrayList<RowRepresentable>()
val session = this.currentSession
val result = session.result
val currency = session.currency
// Headers
when (this.currentSession.getState()) {
SessionState.STARTED -> {
rows.add(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT_BIG,
title = session.getFormattedDuration(),
valueTextFormat = ComputedStat(Stat.NET_RESULT, result?.net ?: 0.0, currency = session.currency).textFormat
)
)
rows.add(SeparatorRow())
}
SessionState.PAUSED -> {
rows.add(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT_BIG,
resId = R.string.pause,
valueTextFormat = ComputedStat(Stat.NET_RESULT, result?.net ?: 0.0, currency = currency).textFormat
)
)
rows.add(SeparatorRow())
}
SessionState.FINISHED -> {
rows.add(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT_BIG,
title = session.getFormattedDuration(),
valueTextFormat = ComputedStat(Stat.NET_RESULT, result?.net ?: 0.0, currency = currency).textFormat
)
)
rows.add(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT,
resId = R.string.hour_rate_without_pauses,
valueTextFormat = ComputedStat(Stat.HOURLY_RATE, session.hourlyRate, currency = currency).textFormat
)
)
// if (!isTournament()) {
// rows.add(
// CustomizableRowRepresentable(
// RowViewType.HEADER_TITLE_VALUE,
// resId = R.string.bankroll_variation,
// computedStat = ComputedStat(Stat.HOURLY_RATE, 0.0, CurrencyUtils.getCurrency(bankroll))
// )
// )
// }
rows.add(SeparatorRow())
}
else -> {
}
}
// Rows
rows.addAll(SessionRow.getRows(this.currentSession, requireContext()))
// Add custom fields
getRealm().let {
rows.add(SeparatorRow())
rows.addAll(it.sorted<CustomField>())
}
return rows
}
fun updateRowRepresentation() {
this.rowRepresentationForCurrentState = this.updatedRowRepresentationForCurrentState(requireContext())
}
override fun adapterRows(): List<RowRepresentable>? {
return this.rowRepresentationForCurrentState
}
override fun boolForRow(row: RowRepresentable): Boolean {
return false
}
override fun charSequenceForRow(row: RowRepresentable, context: Context): String {
return this.currentSession.charSequenceForRow(row, context)
}
override fun actionIconForRow(row: RowRepresentable): Int? {
return when (row) {
SessionRow.START_DATE, SessionRow.END_DATE -> {
R.drawable.ic_close
}
else -> null
}
}
override fun editDescriptors(row: RowRepresentable): List<RowRepresentableEditDescriptor>? {
val session = this.currentSession
return when (row) {
SessionRow.BANKROLL -> row.editingDescriptors(
mapOf(
"defaultValue" to session.bankroll,
"data" to getRealm().sorted<Bankroll>() // LiveData.Bankroll.items(realm)
)
)
SessionRow.GAME -> row.editingDescriptors(
mapOf(
"limit" to session.limit,
"defaultValue" to session.game,
"data" to getRealm().sorted<Game>() //LiveData.Game.items(realm)
)
)
SessionRow.LOCATION -> row.editingDescriptors(
mapOf(
"defaultValue" to session.location,
"data" to getRealm().sorted<Location>() // LiveData.Location.items(realm)
)
)
SessionRow.TOURNAMENT_FEATURE -> row.editingDescriptors(
mapOf(
"defaultValue" to session.tournamentFeatures,
"data" to getRealm().sorted<TournamentFeature>() //LiveData.TournamentFeature.items(realm)
)
)
SessionRow.TOURNAMENT_NAME -> row.editingDescriptors(
mapOf(
"defaultValue" to session.tournamentName,
"data" to getRealm().sorted<TournamentName>() //LiveData.TournamentName.items(realm)
)
)
SessionRow.TOURNAMENT_TYPE -> row.editingDescriptors(
mapOf(
"defaultValue" to session.tournamentType
)
)
SessionRow.TABLE_SIZE -> row.editingDescriptors(
mapOf(
"defaultValue" to session.tableSize
)
)
SessionRow.BLINDS -> row.editingDescriptors(
mapOf(
"sb" to session.cgSmallBlind?.round(),
"bb" to session.cgBigBlind?.round()
)
)
SessionRow.BUY_IN -> row.editingDescriptors(
mapOf(
"bb" to session.cgBigBlind,
"fee" to session.tournamentEntryFee,
"ratedBuyin" to session.result?.buyin
)
)
SessionRow.BREAK_TIME -> row.editingDescriptors(mapOf())
SessionRow.CASHED_OUT, SessionRow.PRIZE -> row.editingDescriptors(
mapOf(
"defaultValue" to session.result?.cashout
)
)
SessionRow.NET_RESULT -> row.editingDescriptors(
mapOf(
"defaultValue" to session.result?.netResult
)
)
SessionRow.COMMENT -> row.editingDescriptors(
mapOf(
"defaultValue" to session.comment
)
)
SessionRow.INITIAL_BUY_IN -> row.editingDescriptors(
mapOf(
"defaultValue" to session.tournamentEntryFee
)
)
SessionRow.PLAYERS -> row.editingDescriptors(
mapOf(
"defaultValue" to session.tournamentNumberOfPlayers
)
)
SessionRow.POSITION -> row.editingDescriptors(
mapOf(
"defaultValue" to session.result?.tournamentFinalPosition
)
)
SessionRow.TIPS -> row.editingDescriptors(
mapOf(
"sb" to session.cgSmallBlind?.round(),
"bb" to session.cgBigBlind?.round(),
"tips" to session.result?.tips
)
)
is CustomField -> {
row.editingDescriptors(
when (row.type) {
CustomField.Type.LIST.uniqueIdentifier -> mapOf(
"defaultValue" to session.customFieldEntries.find { it.customField?.id == row.id }?.value,
"data" to row.entries
)
else -> mapOf(
"defaultValue" to session.customFieldEntries.find { it.customField?.id == row.id }?.numericValue
)
}
)
}
else -> null
}
}
}

@ -14,7 +14,9 @@ enum class BankrollRow : RowRepresentable, DefaultEditDataSource {
INITIAL_VALUE,
CURRENCY,
RATE,
REFRESH_RATE;
REFRESH_RATE,
CAPTURE_BUYIN_CASHEDOUT,
CAPTURE_NET_RESULT;
override val resId: Int?
get() {
@ -24,6 +26,8 @@ enum class BankrollRow : RowRepresentable, DefaultEditDataSource {
CURRENCY -> R.string.currency
RATE -> R.string.rate
REFRESH_RATE -> R.string.refresh_rate
CAPTURE_BUYIN_CASHEDOUT -> R.string.stack_buy_in
CAPTURE_NET_RESULT -> R.string.net_result_only
}
}
@ -35,7 +39,9 @@ enum class BankrollRow : RowRepresentable, DefaultEditDataSource {
CURRENCY -> RowViewType.TITLE_VALUE_ARROW.ordinal
RATE -> RowViewType.TITLE_VALUE.ordinal
REFRESH_RATE -> RowViewType.ROW_BUTTON.ordinal
}
CAPTURE_BUYIN_CASHEDOUT -> RowViewType.TITLE_CHECK.ordinal
CAPTURE_NET_RESULT -> RowViewType.TITLE_CHECK.ordinal
}
}
override val bottomSheetType: BottomSheetType
@ -46,7 +52,9 @@ enum class BankrollRow : RowRepresentable, DefaultEditDataSource {
CURRENCY -> BottomSheetType.NONE
RATE -> BottomSheetType.NUMERIC_TEXT
REFRESH_RATE -> BottomSheetType.NONE
}
CAPTURE_BUYIN_CASHEDOUT -> BottomSheetType.NONE
CAPTURE_NET_RESULT -> BottomSheetType.NONE
}
}
override fun editingDescriptors(map: Map<String, Any?>): ArrayList<RowRepresentableEditDescriptor>? {

@ -1,11 +1,13 @@
package net.pokeranalytics.android.ui.view.rowrepresentable
import android.content.Context
import android.text.InputType
import io.realm.RealmResults
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.TournamentType
import net.pokeranalytics.android.model.extensions.SessionState
import net.pokeranalytics.android.model.extensions.getState
import net.pokeranalytics.android.model.realm.ResultCaptureType
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType
import net.pokeranalytics.android.ui.view.RowRepresentable
@ -44,7 +46,7 @@ enum class SessionRow : RowRepresentable {
/**
* Return the rows to display for the current session state
*/
fun getRows(session: Session): List<RowRepresentable> {
fun getRows(session: Session, context: Context): List<RowRepresentable> {
when (session.type) {
Session.Type.TOURNAMENT.ordinal -> {
return when (session.getState()) {
@ -102,10 +104,13 @@ enum class SessionRow : RowRepresentable {
SessionState.STARTED, SessionState.PAUSED, SessionState.FINISHED -> {
val fields = mutableListOf<RowRepresentable>()
when {
session.hasBuyin -> fields.addAll(listOf(CASHED_OUT, BUY_IN, TIPS))
session.hasNetResult -> fields.add(NET_RESULT)
session.isLive -> fields.addAll(listOf(CASHED_OUT, BUY_IN, TIPS))
when (session.bankroll?.resultCaptureType(context)) {
ResultCaptureType.BUYIN_CASHEDOUT -> fields.addAll(listOf(CASHED_OUT, BUY_IN, TIPS))
ResultCaptureType.NET_RESULT -> fields.add(NET_RESULT)
// session.hasBuyin -> fields.addAll(listOf(CASHED_OUT, BUY_IN, TIPS))
// session.hasNetResult -> fields.add(NET_RESULT)
// session.isLive -> fields.addAll(listOf(CASHED_OUT, BUY_IN, TIPS))
else -> fields.add(NET_RESULT)
}
fields.add(SeparatorRow())

@ -5,7 +5,7 @@ import io.realm.Realm
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.interfaces.Deletable
class DataManagerViewModel : ViewModel() {
open class DataManagerViewModel : ViewModel() {
/***
* A deletable object

@ -7,6 +7,8 @@ import android.view.View
import io.realm.Realm
import net.pokeranalytics.android.PokerAnalyticsApplication
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Bankroll
import net.pokeranalytics.android.model.realm.ResultCaptureType
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.extensions.openUrl
import net.pokeranalytics.android.util.extensions.count
@ -33,7 +35,8 @@ class Preferences {
PATCH_BLINDS_FORMAT("patchBlindFormat"),
SHOW_STOP_NOTIFICATIONS("showStopNotifications"),
ADD_NEW_TRANSACTION_TYPES("addNewTransactionTypes"),
SHOW_VILLAIN_CARDS("showVillainCards")
SHOW_VILLAIN_CARDS("showVillainCards"),
BANKROLL_RESULT_CAPTURE_TYPE("bankrollResultCaptureType_")
}
enum class FeedMessage {
@ -110,6 +113,7 @@ class Preferences {
return preferences.getBoolean(key.identifier, defaultValue ?: false)
}
fun setShowVillainCards(show: Boolean, context: Context) {
setBoolean(Keys.SHOW_VILLAIN_CARDS, show, context)
}
@ -193,7 +197,23 @@ class Preferences {
}
}
}
fun setResultCaptureType(bankroll: Bankroll, type: ResultCaptureType, context: Context) {
val key = "${Keys.BANKROLL_RESULT_CAPTURE_TYPE}${bankroll.id}"
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
val editor = preferences.edit()
editor.putInt(key, type.ordinal)
editor.apply()
}
fun getResultCaptureType(bankroll: Bankroll, context: Context): ResultCaptureType? {
val key = "${Keys.BANKROLL_RESULT_CAPTURE_TYPE}${bankroll.id}"
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
return when (val ordinal = preferences.getInt(key, -1)) {
-1 -> null
else -> ResultCaptureType.values()[ordinal]
}
}
}
}

Loading…
Cancel
Save