Merge branch 'dev' of gitlab.com:stax-river/poker-analytics into dev

feature/top10
Laurent 7 years ago
commit 71d2b9c0ec
  1. 46
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/BankrollInstrumentedUnitTest.kt
  2. 39
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/BlindFilterInstrumentedTest.kt
  3. 40
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/DateFilterInstrumentedUnitTest.kt
  4. 20
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt
  5. 5
      app/src/main/AndroidManifest.xml
  6. 3
      app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt
  7. 8
      app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt
  8. 83
      app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt
  9. 4
      app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt
  10. 12
      app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt
  11. 12
      app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt
  12. 10
      app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt
  13. 37
      app/src/main/java/net/pokeranalytics/android/model/realm/FilterCondition.kt
  14. 8
      app/src/main/java/net/pokeranalytics/android/model/realm/FilterElementBlind.kt
  15. 71
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  16. 7
      app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt
  17. 33
      app/src/main/java/net/pokeranalytics/android/ui/activity/ComparisonChartActivity.kt
  18. 8
      app/src/main/java/net/pokeranalytics/android/ui/activity/GraphActivity.kt
  19. 80
      app/src/main/java/net/pokeranalytics/android/ui/adapter/ComparisonChartPagerAdapter.kt
  20. 8
      app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt
  21. 100
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ComparisonChartFragment.kt
  22. 17
      app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt
  23. 6
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt
  24. 5
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt
  25. 28
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt
  26. 7
      app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt
  27. 2
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt
  28. 19
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt
  29. 33
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt
  30. 64
      app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt
  31. 92
      app/src/main/java/net/pokeranalytics/android/util/Preferences.kt
  32. 11
      app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt
  33. 15
      app/src/main/res/layout/activity_comparison_chart.xml
  34. 26
      app/src/main/res/layout/activity_graph.xml
  35. 57
      app/src/main/res/layout/fragment_comparison_chart.xml
  36. 11
      app/src/main/res/layout/fragment_evograph.xml
  37. 1
      app/src/main/res/values/strings.xml
  38. 9
      app/src/main/res/values/styles.xml

@ -28,53 +28,7 @@ class BankrollInstrumentedUnitTest : RealmInstrumentedUnitTest() {
@Test @Test
fun testSessionStats() { fun testSessionStats() {
val realm = this.mockRealm
realm.beginTransaction()
val s1 = newSessionInstance(realm)
val s2 = newSessionInstance(realm)
val br1 = realm.createObject(Bankroll::class.java, "1")
val br2 = realm.createObject(Bankroll::class.java, "2")
val c1 = realm.createObject(Currency::class.java, "1")
val c2 = realm.createObject(Currency::class.java, "2")
c1.rate = 0.1
c2.rate = 2.0
br1.currency = c1
br2.currency = c2
s1.bankroll = br1
s2.bankroll = br2
s1.result?.netResult = 100.0
s2.result?.netResult = 200.0
realm.commitTransaction()
val computableResults = realm.where(ComputableResult::class.java).findAll()
val sets = realm.where(SessionSet::class.java).findAll()
val stats: List<Stat> = listOf(Stat.NETRESULT, Stat.AVERAGE)
val group = ComputableGroup("test", computableResults, sets, stats)
val options = Calculator.Options()
val results: ComputedResults = Calculator.compute(group, options)
val delta = 0.01
val sum = results.computedStat(Stat.NETRESULT)
if (sum != null) {
Assert.assertEquals(410.0, sum.value, delta)
} else {
Assert.fail("No Net result stat")
}
val average = results.computedStat(Stat.AVERAGE)
if (average != null) {
Assert.assertEquals(205.0, average.value, delta)
} else {
Assert.fail("No AVERAGE stat")
}
} }

@ -21,7 +21,7 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() {
realm.beginTransaction() realm.beginTransaction()
val currency = realm.createObject(net.pokeranalytics.android.model.realm.Currency::class.java, "1") val currency = realm.createObject(net.pokeranalytics.android.model.realm.Currency::class.java, "1")
currency.code = "AUD" currency.code = "USD"
val b1 = realm.createObject(Bankroll::class.java, "1") val b1 = realm.createObject(Bankroll::class.java, "1")
val b2 = realm.createObject(Bankroll::class.java, "2") val b2 = realm.createObject(Bankroll::class.java, "2")
@ -42,9 +42,9 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.BLINDS val filter = QueryCondition.BLIND
val blind = FilterElementRow.Blind(0.5, 1.0, null) val blind = FilterElementRow.Blind(s1.blinds!!, true)
blind.filterSectionRow = FilterSectionRow.BLINDS blind.filterSectionRow = FilterSectionRow.BLIND
val filterElement = FilterCondition(filterElementRows = arrayListOf(blind)) val filterElement = FilterCondition(filterElementRows = arrayListOf(blind))
filter.updateValueMap(filterElement) filter.updateValueMap(filterElement)
@ -86,12 +86,14 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.BLINDS val filter = QueryCondition.BLIND
val blind = FilterElementRow.Blind(null, 1.0, null) val blind1 = FilterElementRow.Blind(s1.blinds!!, true)
blind.filterSectionRow = FilterSectionRow.BLINDS val blind2 = FilterElementRow.Blind(s2.blinds!!, true)
blind1.filterSectionRow = FilterSectionRow.BLIND
blind2.filterSectionRow = FilterSectionRow.BLIND
val filterElement = FilterCondition(filterElementRows = arrayListOf(blind)) val filterElements = FilterCondition(filterElementRows = arrayListOf(blind1, blind2))
filter.updateValueMap(filterElement) filter.updateValueMap(filterElements)
val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter)) val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter))
@ -108,13 +110,14 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() {
realm.beginTransaction() realm.beginTransaction()
val currency = realm.createObject(net.pokeranalytics.android.model.realm.Currency::class.java, "1") val currency = realm.createObject(net.pokeranalytics.android.model.realm.Currency::class.java, "1")
currency.code = "AUD" currency.code = "USD"
val b1 = realm.createObject(Bankroll::class.java, "1") val b1 = realm.createObject(Bankroll::class.java, "1")
val b2 = realm.createObject(Bankroll::class.java, "2") val b2 = realm.createObject(Bankroll::class.java, "2")
b2.currency = currency b2.currency = currency
val s1 = Session.testInstance(100.0, false, Date(), 1, b1) val s1 = Session.testInstance(100.0, false, Date(), 1, b1)
s1.cgBigBlind = 1.0 s1.cgBigBlind = 1.0
s1.cgSmallBlind = 0.5 s1.cgSmallBlind = 0.5
@ -129,9 +132,9 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.BLINDS val filter = QueryCondition.BLIND
val blind = FilterElementRow.Blind(1.0, 2.0, "AUD") val blind = FilterElementRow.Blind(s3.blinds!!, false)
blind.filterSectionRow = FilterSectionRow.BLINDS blind.filterSectionRow = FilterSectionRow.BLIND
val filterElement = FilterCondition(filterElementRows = arrayListOf(blind)) val filterElement = FilterCondition(filterElementRows = arrayListOf(blind))
filter.updateValueMap(filterElement) filter.updateValueMap(filterElement)
@ -172,12 +175,12 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.BLINDS val filter = QueryCondition.BLIND
val blind1 = FilterElementRow.Blind(1.0, 2.0, null) val blind1 = FilterElementRow.Blind(s1.blinds!!, false)
blind1.filterSectionRow = FilterSectionRow.BLINDS blind1.filterSectionRow = FilterSectionRow.BLIND
val blind2 = FilterElementRow.Blind(0.5, 1.0, null) val blind2 = FilterElementRow.Blind(s2.blinds!!, false)
blind2.filterSectionRow = FilterSectionRow.BLINDS blind2.filterSectionRow = FilterSectionRow.BLIND
val filterElement = FilterCondition(filterElementRows = arrayListOf(blind1, blind2)) val filterElement = FilterCondition(filterElementRows = arrayListOf(blind1, blind2))
filter.updateValueMap(filterElement) filter.updateValueMap(filterElement)

@ -35,14 +35,14 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filterElementRow = FilterElementRow.Day(cal.get(Calendar.DAY_OF_WEEK)) val filterElementRow = FilterElementRow.Day(cal.get(Calendar.DAY_OF_WEEK))
filterElementRow.filterSectionRow = FilterSectionRow.DYNAMIC_DATE filterElementRow.filterSectionRow = FilterSectionRow.DYNAMIC_DATE
val filterElement = FilterCondition(filterElementRow) val filterElement = FilterCondition(arrayListOf(filterElementRow))
filter.updateValueMap(filterElement) filter.updateValueMap(filterElement)
val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter)) val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter))
Assert.assertEquals(1, sessions.size) Assert.assertEquals(1, sessions.size)
sessions[0]?.run { sessions[0]?.run {
Assert.assertEquals(s1.id, (this as Session).id) Assert.assertEquals(s1.id, (this).id)
} }
} }
@ -64,14 +64,14 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filterElementRow = FilterElementRow.Month(cal.get(Calendar.MONTH)) val filterElementRow = FilterElementRow.Month(cal.get(Calendar.MONTH))
filterElementRow.filterSectionRow = FilterSectionRow.DYNAMIC_DATE filterElementRow.filterSectionRow = FilterSectionRow.DYNAMIC_DATE
val filterElement = FilterCondition(filterElementRow) val filterElement = FilterCondition(arrayListOf(filterElementRow))
filter.updateValueMap(filterElement) filter.updateValueMap(filterElement)
val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter)) val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter))
Assert.assertEquals(1, sessions.size) Assert.assertEquals(1, sessions.size)
sessions[0]?.run { sessions[0]?.run {
Assert.assertEquals(s1.id, (this as Session).id) Assert.assertEquals(s1.id, (this).id)
} }
} }
@ -92,14 +92,14 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
cal.time = s1.startDate cal.time = s1.startDate
val filterElementRow = FilterElementRow.Year(cal.get(Calendar.YEAR)) val filterElementRow = FilterElementRow.Year(cal.get(Calendar.YEAR))
filterElementRow.filterSectionRow = FilterSectionRow.DYNAMIC_DATE filterElementRow.filterSectionRow = FilterSectionRow.DYNAMIC_DATE
val filterElement = FilterCondition(filterElementRow) val filterElement = FilterCondition(arrayListOf(filterElementRow))
filter.updateValueMap(filterElement) filter.updateValueMap(filterElement)
val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter)) val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter))
Assert.assertEquals(1, sessions.size) Assert.assertEquals(1, sessions.size)
sessions[0]?.run { sessions[0]?.run {
Assert.assertEquals(s1.id, (this as Session).id) Assert.assertEquals(s1.id, (this).id)
} }
} }
@ -122,7 +122,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
Assert.assertEquals(1, sessions.size) Assert.assertEquals(1, sessions.size)
sessions[0]?.run { sessions[0]?.run {
Assert.assertEquals(s1.id, (this as Session).id) Assert.assertEquals(s1.id, (this).id)
} }
} }
@ -147,7 +147,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
Assert.assertEquals(1, sessions.size) Assert.assertEquals(1, sessions.size)
sessions[0]?.run { sessions[0]?.run {
Assert.assertEquals(s1.id, (this as Session).id) Assert.assertEquals(s1.id, (this).id)
} }
} }
@ -384,15 +384,15 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.STARTED_FROM_DATE val filter = QueryCondition.STARTED_FROM_DATE
val filterElementRow = FilterElementRow.From(s2.startDate!!) val filterElementRow = FilterElementRow.From.apply { dateValue = s2.startDate!!}
filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE
filter.updateValueMap(FilterCondition(filterElementRow)) filter.updateValueMap(FilterCondition(arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter)) val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter))
Assert.assertEquals(1, sessions.size) Assert.assertEquals(1, sessions.size)
sessions[0]?.run { sessions[0]?.run {
Assert.assertEquals(s2.id, (this as Session).id) Assert.assertEquals(s2.id, (this).id)
} }
} }
@ -412,15 +412,15 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.STARTED_TO_DATE val filter = QueryCondition.STARTED_TO_DATE
val filterElementRow = FilterElementRow.From(s1.startDate!!) val filterElementRow = FilterElementRow.From.apply { dateValue = s1.startDate!! }
filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE
filter.updateValueMap(FilterCondition(filterElementRow)) filter.updateValueMap(FilterCondition(arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter)) val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter))
Assert.assertEquals(1, sessions.size) Assert.assertEquals(1, sessions.size)
sessions[0]?.run { sessions[0]?.run {
Assert.assertEquals(s1.id, (this as Session).id) Assert.assertEquals(s1.id, (this).id)
} }
} }
@ -441,15 +441,15 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.ENDED_FROM_DATE val filter = QueryCondition.ENDED_FROM_DATE
val filterElementRow = FilterElementRow.From(s2.endDate()) val filterElementRow = FilterElementRow.From.apply { dateValue = s2.endDate() }
filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE
filter.updateValueMap(FilterCondition(filterElementRow)) filter.updateValueMap(FilterCondition(arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter)) val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter))
Assert.assertEquals(1, sessions.size) Assert.assertEquals(1, sessions.size)
sessions[0]?.run { sessions[0]?.run {
Assert.assertEquals(s2.id, (this as Session).id) Assert.assertEquals(s2.id, (this).id)
} }
} }
@ -470,15 +470,15 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.ENDED_TO_DATE val filter = QueryCondition.ENDED_TO_DATE
val filterElementRow = FilterElementRow.From(s1.endDate()) val filterElementRow = FilterElementRow.From.apply { dateValue = s1.endDate() }
filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE
filter.updateValueMap(FilterCondition(filterElementRow)) filter.updateValueMap(FilterCondition(arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter)) val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter))
Assert.assertEquals(1, sessions.size) Assert.assertEquals(1, sessions.size)
sessions[0]?.run { sessions[0]?.run {
Assert.assertEquals(s1.id, (this as Session).id) Assert.assertEquals(s1.id, (this).id)
} }
} }
} }

@ -30,7 +30,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
Assert.assertEquals(1, sessions.size) Assert.assertEquals(1, sessions.size)
sessions[0]?.run { sessions[0]?.run {
Assert.assertEquals(Session.Type.CASH_GAME.ordinal, (this as Session).type) Assert.assertEquals(Session.Type.CASH_GAME.ordinal, (this).type)
} }
} }
@ -48,7 +48,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
Assert.assertEquals(1, sessions.size) Assert.assertEquals(1, sessions.size)
sessions[0]?.run { sessions[0]?.run {
Assert.assertEquals(Session.Type.TOURNAMENT.ordinal, (this as Session).type) Assert.assertEquals(Session.Type.TOURNAMENT.ordinal, (this).type)
} }
} }
@ -480,9 +480,9 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.MORE_THAN_NET_RESULT val filter = QueryCondition.MORE_THAN_NET_RESULT
val filterElementRow = FilterElementRow.ResultMoreThan(204.0) val filterElementRow = FilterElementRow.ResultMoreThan.apply { this.amount = 204.0 }
filterElementRow.filterSectionRow = FilterSectionRow.VALUE filterElementRow.filterSectionRow = FilterSectionRow.VALUE
filter.updateValueMap(FilterCondition(filterElementRow)) filter.updateValueMap(FilterCondition(arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter)) val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter))
@ -505,9 +505,9 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.LESS_THAN_NET_RESULT val filter = QueryCondition.LESS_THAN_NET_RESULT
val filterElementRow = FilterElementRow.ResultLessThan(540.0) val filterElementRow = FilterElementRow.ResultMoreThan.apply { this.amount = 540.0 }
filterElementRow.filterSectionRow = FilterSectionRow.VALUE filterElementRow.filterSectionRow = FilterSectionRow.VALUE
filter.updateValueMap(FilterCondition(filterElementRow)) filter.updateValueMap(FilterCondition(arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter)) val sessions = Filter.queryOn<Session>(realm, arrayListOf(filter))
@ -530,14 +530,14 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filterMore = QueryCondition.MORE_THAN_NET_RESULT val filterMore = QueryCondition.MORE_THAN_NET_RESULT
val filterElementRow = FilterElementRow.ResultMoreThan(200.0) val filterElementRow = FilterElementRow.ResultMoreThan.apply { this.amount = 200.0 }
filterElementRow.filterSectionRow = FilterSectionRow.VALUE filterElementRow.filterSectionRow = FilterSectionRow.VALUE
filterMore.updateValueMap(FilterCondition(filterElementRow)) filterMore.updateValueMap(FilterCondition(arrayListOf(filterElementRow)))
val filterLess = QueryCondition.LESS_THAN_NET_RESULT val filterLess = QueryCondition.LESS_THAN_NET_RESULT
val filterElementRow2 = FilterElementRow.ResultLessThan(400.0) val filterElementRow2 = FilterElementRow.ResultMoreThan.apply { this.amount = 400.0 }
filterElementRow2.filterSectionRow = FilterSectionRow.VALUE filterElementRow2.filterSectionRow = FilterSectionRow.VALUE
filterLess.updateValueMap(FilterCondition(filterElementRow2)) filterLess.updateValueMap(FilterCondition(arrayListOf(filterElementRow2)))
val sessions = Filter.queryOn<Session>(realm, arrayListOf(filterMore, filterLess)) val sessions = Filter.queryOn<Session>(realm, arrayListOf(filterMore, filterLess))

@ -44,6 +44,11 @@
android:launchMode="singleTop" android:launchMode="singleTop"
android:screenOrientation="portrait" /> android:screenOrientation="portrait" />
<activity
android:name=".ui.activity.ComparisonChartActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
<activity <activity
android:name=".ui.activity.DataListActivity" android:name=".ui.activity.DataListActivity"
android:launchMode="singleTop" android:launchMode="singleTop"

@ -14,6 +14,7 @@ import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.utils.Seed import net.pokeranalytics.android.model.utils.Seed
import net.pokeranalytics.android.util.FakeDataManager import net.pokeranalytics.android.util.FakeDataManager
import net.pokeranalytics.android.util.PokerAnalyticsLogs import net.pokeranalytics.android.util.PokerAnalyticsLogs
import net.pokeranalytics.android.util.UserDefaults
import timber.log.Timber import timber.log.Timber
@ -22,6 +23,8 @@ class PokerAnalyticsApplication : Application() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
UserDefaults.init(this)
println("UserPreferences.defaultCurrency: ${UserDefaults.currency.symbol}")
// Realm // Realm
Realm.init(this) Realm.init(this)

@ -7,10 +7,10 @@ import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.model.interfaces.Timed import net.pokeranalytics.android.model.interfaces.Timed
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.util.CurrencyUtils
import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.extensions.formatted import net.pokeranalytics.android.util.extensions.formatted
import net.pokeranalytics.android.util.extensions.formattedHourlyDuration import net.pokeranalytics.android.util.extensions.formattedHourlyDuration
import net.pokeranalytics.android.util.extensions.toCurrency
import java.util.* import java.util.*
class StatFormattingException(message: String) : Exception(message) { class StatFormattingException(message: String) : Exception(message) {
@ -136,9 +136,8 @@ enum class Stat : RowRepresentable {
when (this) { when (this) {
// Amounts + red/green // Amounts + red/green
Stat.NETRESULT, Stat.HOURLY_RATE, Stat.AVERAGE -> { Stat.NETRESULT, Stat.HOURLY_RATE, Stat.AVERAGE -> {
val numberFormat = CurrencyUtils.getCurrencyFormatter(context, currency)
val color = if (value >= this.threshold) R.color.green else R.color.red val color = if (value >= this.threshold) R.color.green else R.color.red
return TextFormat(numberFormat.format(value), color) return TextFormat(value.toCurrency(currency), color)
} }
// Red/green numericValues // Red/green numericValues
Stat.HOURLY_RATE_BB, Stat.AVERAGE_NET_BB, Stat.NET_BB_PER_100_HANDS -> { Stat.HOURLY_RATE_BB, Stat.AVERAGE_NET_BB, Stat.NET_BB_PER_100_HANDS -> {
@ -158,8 +157,7 @@ enum class Stat : RowRepresentable {
} // white amountsr } // white amountsr
Stat.AVERAGE_BUYIN, Stat.STANDARD_DEVIATION, Stat.STANDARD_DEVIATION_HOURLY, Stat.AVERAGE_BUYIN, Stat.STANDARD_DEVIATION, Stat.STANDARD_DEVIATION_HOURLY,
Stat.STANDARD_DEVIATION_BB_PER_100_HANDS -> { Stat.STANDARD_DEVIATION_BB_PER_100_HANDS -> {
val numberFormat = CurrencyUtils.getCurrencyFormatter(context, currency) return TextFormat(value.toCurrency(currency))
return TextFormat(numberFormat.format(value))
} }
else -> throw FormattingException("Stat formatting of ${this.name} not handled") else -> throw FormattingException("Stat formatting of ${this.name} not handled")
} }

@ -1,12 +1,9 @@
package net.pokeranalytics.android.model.filter package net.pokeranalytics.android.model.filter
import io.realm.RealmList
import io.realm.RealmQuery import io.realm.RealmQuery
import net.pokeranalytics.android.exceptions.PokerAnalyticsException import net.pokeranalytics.android.exceptions.PokerAnalyticsException
import net.pokeranalytics.android.model.realm.FilterCondition import net.pokeranalytics.android.model.realm.FilterCondition
import net.pokeranalytics.android.model.realm.FilterElementBlind
import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.extensions.endOfDay import net.pokeranalytics.android.util.extensions.endOfDay
import net.pokeranalytics.android.util.extensions.startOfDay import net.pokeranalytics.android.util.extensions.startOfDay
import java.util.* import java.util.*
@ -32,7 +29,7 @@ enum class QueryCondition(var operator: Operator? = null) {
LIMIT, LIMIT,
TABLE_SIZE, TABLE_SIZE,
TOURNAMENT_TYPE, TOURNAMENT_TYPE,
BLINDS, BLIND,
LAST_GAMES, LAST_GAMES,
LAST_SESSIONS, LAST_SESSIONS,
MORE_NUMBER_OF_TABLE(Operator.MORE), MORE_NUMBER_OF_TABLE(Operator.MORE),
@ -77,10 +74,6 @@ enum class QueryCondition(var operator: Operator? = null) {
STARTED_FROM_TIME, STARTED_FROM_TIME,
ENDED_TO_TIME, ENDED_TO_TIME,
CURRENCY,
CURRENCY_CODE,
BIG_BLIND,
SMALL_BLIND,
COMMENT, COMMENT,
; ;
@ -118,7 +111,7 @@ enum class QueryCondition(var operator: Operator? = null) {
return when (this) { return when (this) {
BANKROLL, GAME, LOCATION, ANY_TOURNAMENT_FEATURES, ALL_TOURNAMENT_FEATURES, TOURNAMENT_NAME -> arrayOf("ids") BANKROLL, GAME, LOCATION, ANY_TOURNAMENT_FEATURES, ALL_TOURNAMENT_FEATURES, TOURNAMENT_NAME -> arrayOf("ids")
LIMIT, TOURNAMENT_TYPE, TABLE_SIZE -> arrayOf("values") LIMIT, TOURNAMENT_TYPE, TABLE_SIZE -> arrayOf("values")
BLINDS -> arrayOf("blinds") BLIND -> arrayOf("blinds", "hasDefaultCurrency")
STARTED_FROM_DATE, STARTED_TO_DATE, ENDED_FROM_DATE, ENDED_TO_DATE -> arrayOf("date") STARTED_FROM_DATE, STARTED_TO_DATE, ENDED_FROM_DATE, ENDED_TO_DATE -> arrayOf("date")
DAY_OF_WEEK -> arrayOf("dayOfWeek") DAY_OF_WEEK -> arrayOf("dayOfWeek")
MONTH -> arrayOf("month") MONTH -> arrayOf("month")
@ -132,50 +125,8 @@ enum class QueryCondition(var operator: Operator? = null) {
* providing a base RealmQuery [realmQuery], the method is able to attached the corresponding query and returns the newly formed [RealmQuery] * providing a base RealmQuery [realmQuery], the method is able to attached the corresponding query and returns the newly formed [RealmQuery]
*/ */
inline fun <reified T : Filterable> filter(realmQuery: RealmQuery<T>): RealmQuery<T> { inline fun <reified T : Filterable> filter(realmQuery: RealmQuery<T>): RealmQuery<T> {
when {
this == BLINDS -> {
val smallBlindFieldName = FilterHelper.fieldNameForQueryType<T>(SMALL_BLIND)
val bigBlindFieldName = FilterHelper.fieldNameForQueryType<T>(BIG_BLIND)
val currencyCodeFieldName = FilterHelper.fieldNameForQueryType<T>(CURRENCY_CODE)
smallBlindFieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown
bigBlindFieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown
currencyCodeFieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown
val blinds: RealmList<FilterElementBlind> by valueMap
blinds.forEachIndexed { index, blind ->
realmQuery
.beginGroup()
blind.sb?.let {
realmQuery
.equalTo(smallBlindFieldName, it)
.and()
}
realmQuery
.equalTo(bigBlindFieldName, blind.bb)
.and()
blind.currencyCode?.let {
realmQuery.equalTo(currencyCodeFieldName, it)
} ?: run {
realmQuery.isNull(currencyCodeFieldName)
}
realmQuery.endGroup()
if (index < blinds.size - 1) {
realmQuery.or()
}
}
return realmQuery
}
else -> {
val fieldName = FilterHelper.fieldNameForQueryType<T>(this) val fieldName = FilterHelper.fieldNameForQueryType<T>(this)
fieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown fieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown
when (operator) { when (operator) {
Operator.LESS -> { Operator.LESS -> {
val value: Double by valueMap val value: Double by valueMap
@ -207,6 +158,27 @@ enum class QueryCondition(var operator: Operator? = null) {
val ids: Array<String> by valueMap val ids: Array<String> by valueMap
realmQuery.`in`(fieldName, ids) realmQuery.`in`(fieldName, ids)
} }
BLIND -> {
val blinds: Array<String> by valueMap
val hasDefaultCurrency: Array<Boolean> by valueMap
//realmQuery.`in`(fieldName, blinds)
blinds.forEachIndexed { index, s ->
val isUsingDefaultCurrency = hasDefaultCurrency[index]
realmQuery.beginGroup()
if (isUsingDefaultCurrency) {
realmQuery.endsWith(fieldName, s)
.and()
.isNull("bankroll.currency.code")
} else {
realmQuery.equalTo(fieldName, s)
}
.endGroup()
if (index < blinds.size - 1) {
realmQuery.or()
}
}
realmQuery
}
BANKROLL, GAME, LOCATION, TOURNAMENT_NAME -> { BANKROLL, GAME, LOCATION, TOURNAMENT_NAME -> {
val ids: Array<String> by valueMap val ids: Array<String> by valueMap
realmQuery.`in`(fieldName, ids) realmQuery.`in`(fieldName, ids)
@ -293,9 +265,6 @@ enum class QueryCondition(var operator: Operator? = null) {
} }
} }
} }
}
}
fun updateValueMap(filterCondition: FilterCondition) { fun updateValueMap(filterCondition: FilterCondition) {
if (filterValuesExpectedKeys == null) { if (filterValuesExpectedKeys == null) {
@ -314,8 +283,10 @@ enum class QueryCondition(var operator: Operator? = null) {
LIMIT, TOURNAMENT_TYPE, TABLE_SIZE -> { LIMIT, TOURNAMENT_TYPE, TABLE_SIZE -> {
valueMap = mapOf("values" to filterCondition.values) valueMap = mapOf("values" to filterCondition.values)
} }
BLINDS -> { BLIND -> {
valueMap = mapOf("blinds" to filterCondition.blinds) valueMap = mapOf(
"blinds" to filterCondition.blinds,
"hasDefaultCurrency" to filterCondition.hasDefaultCurrency)
} }
STARTED_FROM_DATE, STARTED_TO_DATE, ENDED_FROM_DATE, ENDED_TO_DATE -> { STARTED_FROM_DATE, STARTED_TO_DATE, ENDED_FROM_DATE, ENDED_TO_DATE -> {
valueMap = mapOf("date" to filterCondition.date) valueMap = mapOf("date" to filterCondition.date)

@ -35,7 +35,9 @@ class PokerAnalyticsMigration : RealmMigration {
// Migrate to version 2 // Migrate to version 2
if (currentVersion == 1) { if (currentVersion == 1) {
Timber.d("*** Running migration ${currentVersion + 1}") Timber.d("*** Running migration ${currentVersion + 1}")
schema.get("Session")?.let {
it.addField("blinds", String::class.java).setNullable("blinds", true)
}
schema.rename("FilterElement", "FilterCondition") schema.rename("FilterElement", "FilterCondition")
schema.get("Filter")?.let { schema.get("Filter")?.let {
it.renameField("filterElements", "filterConditions") it.renameField("filterElements", "filterConditions")

@ -3,6 +3,8 @@ package net.pokeranalytics.android.model.realm
import io.realm.Realm import io.realm.Realm
import io.realm.RealmList import io.realm.RealmList
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.LinkingObjects
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
@ -32,6 +34,9 @@ open class Bankroll() : RealmObject(), NameManageable, StaticRowRepresentableDat
} }
} }
@LinkingObjects("bankroll")
private val sessions: RealmResults<Session>? = null
@PrimaryKey @PrimaryKey
override var id = UUID.randomUUID().toString() override var id = UUID.randomUUID().toString()
@ -46,6 +51,12 @@ open class Bankroll() : RealmObject(), NameManageable, StaticRowRepresentableDat
// The currency of the bankroll // The currency of the bankroll
var currency: Currency? = null var currency: Currency? = null
fun currencyCodeHasBeenUpdated() {
sessions?.forEach {
it.bankrollHasBeenUpdated()
}
}
override fun getDisplayName(): String { override fun getDisplayName(): String {
return this.name return this.name
} }
@ -86,6 +97,7 @@ open class Bankroll() : RealmObject(), NameManageable, StaticRowRepresentableDat
this.live = if (value is Boolean) !value else false this.live = if (value is Boolean) !value else false
} }
BankrollRow.CURRENCY -> { BankrollRow.CURRENCY -> {
//TODO handle a use default currency option
this.currency?.code = value as String? this.currency?.code = value as String?
} }
BankrollRow.RATE -> { BankrollRow.RATE -> {

@ -1,8 +1,11 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.Ignore import io.realm.annotations.Ignore
import io.realm.annotations.LinkingObjects
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import net.pokeranalytics.android.util.Preferences
import java.util.* import java.util.*
open class Currency : RealmObject() { open class Currency : RealmObject() {
@ -13,10 +16,19 @@ open class Currency : RealmObject() {
@PrimaryKey @PrimaryKey
var id = UUID.randomUUID().toString() var id = UUID.randomUUID().toString()
@LinkingObjects("currency")
private val bankrolls: RealmResults<Bankroll>? = null
/** /**
* The currency code of the currency, i.e. USD, EUR... * The currency code of the currency, i.e. USD, EUR...
*/ */
var code: String? = null var code: String? = null
set(value) {
field = value
bankrolls?.forEach {
it.currencyCodeHasBeenUpdated()
}
}
/** /**
* The rate of the currency with the main currency * The rate of the currency with the main currency

@ -65,7 +65,7 @@ open class Filter : RealmObject() {
private set private set
fun createOrUpdateFilterConditions(filterConditionRows: ArrayList<FilterElementRow>) { fun createOrUpdateFilterConditions(filterConditionRows: ArrayList<FilterElementRow>) {
filterConditions.clear() val casted = arrayListOf<FilterElementRow>()
filterConditionRows filterConditionRows
.map { .map {
it.filterName it.filterName
@ -77,9 +77,13 @@ open class Filter : RealmObject() {
it.filterName == filterName it.filterName == filterName
} }
.apply { .apply {
val casted = arrayListOf<FilterElementRow>()
casted.addAll(this) casted.addAll(this)
filterConditions.add(FilterCondition(casted)) val newFilterCondition = FilterCondition(casted)
val previousCondition = filterConditions.filter {
it.sectionName == newFilterCondition.filterName
}
filterConditions.removeAll(previousCondition)
filterConditions.add(newFilterCondition)
} }
} }
} }

@ -23,6 +23,19 @@ open class FilterCondition() : RealmObject() {
is DateFilterElementRow -> { is DateFilterElementRow -> {
this.dateValue = row.dateValue this.dateValue = row.dateValue
} }
is Blind -> {
//TODO refactor raz
this.stringValues = RealmList<String>().apply {
this.addAll(filterElementRows.map {
(it as Blind).blind
})
}
this.booleanValues = RealmList<Boolean>().apply {
this.addAll(filterElementRows.map {
(it as Blind).hasDefaultCurrency
})
}
}
is StringFilterElementRow -> { is StringFilterElementRow -> {
this.stringValues = RealmList<String>().apply { this.stringValues = RealmList<String>().apply {
this.addAll(filterElementRows.map { this.addAll(filterElementRows.map {
@ -37,13 +50,6 @@ open class FilterCondition() : RealmObject() {
}) })
} }
} }
is FilterElementBlind -> {
this.blindValues = RealmList<FilterElementBlind>().apply {
this.addAll(filterElementRows.map {
FilterElementBlind((it as FilterElementRow.Blind).sb, it.bb, it.code)
})
}
}
} }
} }
@ -59,23 +65,16 @@ open class FilterCondition() : RealmObject() {
private var numericValues: RealmList<Double>? = null private var numericValues: RealmList<Double>? = null
private var dateValue: Date? = null private var dateValue: Date? = null
private var stringValues: RealmList<String>? = null private var stringValues: RealmList<String>? = null
private var blindValues: RealmList<FilterElementBlind>? = null private var booleanValues: RealmList<Boolean>? = null
val ids: Array<String> val ids: Array<String>
get() = stringValues?.toTypedArray() ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing get() = stringValues?.toTypedArray() ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing
val blinds: RealmList<FilterElementBlind> val blinds: Array<String>
get() { get() = stringValues?.toTypedArray() ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing
blindValues?.let {
if (it.isNotEmpty()) {
return it
} else {
throw PokerAnalyticsException.FilterElementExpectedValueMissing
}
}
throw PokerAnalyticsException.FilterElementExpectedValueMissing
}
val hasDefaultCurrency: Array<Boolean>
get() = booleanValues?.toTypedArray() ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing
val date: Date val date: Date
get() = dateValue ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing get() = dateValue ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing

@ -1,8 +0,0 @@
package net.pokeranalytics.android.model.realm
import io.realm.RealmObject
open class FilterElementBlind(var sb : Double? = null,
var bb : Double? = null,
var currencyCode : String? = null
) : RealmObject()

@ -32,8 +32,8 @@ import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow
import net.pokeranalytics.android.util.CurrencyUtils
import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.UserDefaults
import net.pokeranalytics.android.util.extensions.* import net.pokeranalytics.android.util.extensions.*
import java.util.* import java.util.*
import java.util.Currency import java.util.Currency
@ -74,10 +74,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
LIMIT -> "limit" LIMIT -> "limit"
TABLE_SIZE -> "tableSize" TABLE_SIZE -> "tableSize"
TOURNAMENT_TYPE -> "tournamentType" TOURNAMENT_TYPE -> "tournamentType"
CURRENCY -> "bankroll.currency" BLIND -> "blind"
CURRENCY_CODE -> "bankroll.currency.code"
BIG_BLIND -> "cgBigBlind"
SMALL_BLIND -> "cgSmallBlind"
COMMENT -> "comment" COMMENT -> "comment"
BETWEEN_NUMBER_OF_TABLE, MORE_NUMBER_OF_TABLE, LESS_NUMBER_OF_TABLE -> "numberOfTable" BETWEEN_NUMBER_OF_TABLE, MORE_NUMBER_OF_TABLE, LESS_NUMBER_OF_TABLE -> "numberOfTable"
MORE_THAN_NET_RESULT, LESS_THAN_NET_RESULT -> "computableResults.ratedNet" MORE_THAN_NET_RESULT, LESS_THAN_NET_RESULT -> "computableResults.ratedNet"
@ -216,14 +213,22 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
// The small blind value // The small blind value
var cgSmallBlind: Double? = null var cgSmallBlind: Double? = null
set(value) {
field = value
formatBlinds()
}
// The big blind value // The big blind value
var cgBigBlind: Double? = null var cgBigBlind: Double? = null
set(value) { set(value) {
field = value field = value
this.computeStats() this.computeStats()
formatBlinds()
} }
var blinds: String? = null
private set
// Tournament // Tournament
// The entry fee of the tournament // The entry fee of the tournament
@ -241,6 +246,10 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
// The features of the tournament, like Knockout, Shootout, Turbo... // The features of the tournament, like Knockout, Shootout, Turbo...
var tournamentFeatures: RealmList<TournamentFeature> = RealmList() var tournamentFeatures: RealmList<TournamentFeature> = RealmList()
fun bankrollHasBeenUpdated() {
formatBlinds()
}
/** /**
* Manages impacts on SessionSets * Manages impacts on SessionSets
* Should be called when the start / end date are changed * Should be called when the start / end date are changed
@ -478,13 +487,18 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
return NULL_TEXT return NULL_TEXT
} }
/** val hasDefaultCurrency: Boolean
* Return the formatted blinds get() {
*/ return bankroll?.currency?.code == null
fun getBlinds(): String { }
val currencyCode = bankroll?.currency?.code ?: CurrencyUtils.getLocaleCurrency().currencyCode
val currencySymbol = Currency.getInstance(currencyCode).symbol val currency : Currency
return if (cgSmallBlind == null) NULL_TEXT else "$currencySymbol ${cgSmallBlind?.formatted()}/${cgBigBlind?.round()}" get() {
return bankroll?.currency?.code?.let {
Currency.getInstance(it)
} ?: run {
UserDefaults.currency
}
} }
/** /**
@ -504,6 +518,19 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
return if (gameTitle.isNotBlank()) gameTitle else NULL_TEXT return if (gameTitle.isNotBlank()) gameTitle else NULL_TEXT
} }
fun getFormattedBlinds(): String {
return blinds ?: NULL_TEXT
}
private fun formatBlinds() {
blinds = null
if (cgBigBlind == null) return
cgBigBlind?.let { bb ->
val sb = cgSmallBlind ?: bb / 2.0
blinds = "${currency.symbol} ${sb.formatted()}/${bb.round()}"
}
}
// LifeCycle // LifeCycle
/** /**
@ -554,7 +581,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
CustomizableRowRepresentable( CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT_BIG, RowViewType.HEADER_TITLE_AMOUNT_BIG,
title = getFormattedDuration(), title = getFormattedDuration(),
computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0, CurrencyUtils.getCurrency(bankroll)) computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0, currency)
) )
) )
rows.add(SeparatorRowRepresentable()) rows.add(SeparatorRowRepresentable())
@ -564,7 +591,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
CustomizableRowRepresentable( CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT_BIG, RowViewType.HEADER_TITLE_AMOUNT_BIG,
resId = R.string.pause, resId = R.string.pause,
computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0, CurrencyUtils.getCurrency(bankroll)) computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0, currency)
) )
) )
rows.add(SeparatorRowRepresentable()) rows.add(SeparatorRowRepresentable())
@ -574,14 +601,14 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
CustomizableRowRepresentable( CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT_BIG, RowViewType.HEADER_TITLE_AMOUNT_BIG,
title = getFormattedDuration(), title = getFormattedDuration(),
computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0, CurrencyUtils.getCurrency(bankroll)) computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0, currency)
) )
) )
rows.add( rows.add(
CustomizableRowRepresentable( CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT, RowViewType.HEADER_TITLE_AMOUNT,
resId = R.string.hour_rate_without_pauses, resId = R.string.hour_rate_without_pauses,
computedStat = ComputedStat(Stat.HOURLY_RATE, this.hourlyRate, CurrencyUtils.getCurrency(bankroll)) computedStat = ComputedStat(Stat.HOURLY_RATE, this.hourlyRate, currency)
) )
) )
@ -620,20 +647,20 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
override fun stringForRow(row: RowRepresentable, context: Context): String { override fun stringForRow(row: RowRepresentable, context: Context): String {
return when (row) { return when (row) {
SessionRow.BANKROLL -> bankroll?.name ?: NULL_TEXT SessionRow.BANKROLL -> bankroll?.name ?: NULL_TEXT
SessionRow.BLINDS -> getBlinds() SessionRow.BLINDS -> getFormattedBlinds()
SessionRow.BREAK_TIME -> if (this.breakDuration > 0.0) this.breakDuration.toMinutes() else NULL_TEXT SessionRow.BREAK_TIME -> if (this.breakDuration > 0.0) this.breakDuration.toMinutes() else NULL_TEXT
SessionRow.BUY_IN -> this.result?.buyin?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT SessionRow.BUY_IN -> this.result?.buyin?.toCurrency(currency) ?: NULL_TEXT
SessionRow.CASHED_OUT, SessionRow.PRIZE, SessionRow.NET_RESULT -> this.result?.cashout?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT SessionRow.CASHED_OUT, SessionRow.PRIZE, SessionRow.NET_RESULT -> this.result?.cashout?.toCurrency(currency) ?: NULL_TEXT
SessionRow.COMMENT -> if (this.comment.isNotEmpty()) this.comment else NULL_TEXT SessionRow.COMMENT -> if (this.comment.isNotEmpty()) this.comment else NULL_TEXT
SessionRow.END_DATE -> this.endDate?.shortDateTime() ?: NULL_TEXT SessionRow.END_DATE -> this.endDate?.shortDateTime() ?: NULL_TEXT
SessionRow.GAME -> getFormattedGame() SessionRow.GAME -> getFormattedGame()
SessionRow.INITIAL_BUY_IN -> tournamentEntryFee?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT SessionRow.INITIAL_BUY_IN -> tournamentEntryFee?.toCurrency(currency) ?: NULL_TEXT
SessionRow.LOCATION -> location?.name ?: NULL_TEXT SessionRow.LOCATION -> location?.name ?: NULL_TEXT
SessionRow.PLAYERS -> tournamentNumberOfPlayers?.toString() ?: NULL_TEXT SessionRow.PLAYERS -> tournamentNumberOfPlayers?.toString() ?: NULL_TEXT
SessionRow.POSITION -> result?.tournamentFinalPosition?.toString() ?: NULL_TEXT SessionRow.POSITION -> result?.tournamentFinalPosition?.toString() ?: NULL_TEXT
SessionRow.START_DATE -> this.startDate?.shortDateTime() ?: NULL_TEXT SessionRow.START_DATE -> this.startDate?.shortDateTime() ?: NULL_TEXT
SessionRow.TABLE_SIZE -> this.tableSize?.let { TableSize(it).localizedTitle(context) } ?: NULL_TEXT SessionRow.TABLE_SIZE -> this.tableSize?.let { TableSize(it).localizedTitle(context) } ?: NULL_TEXT
SessionRow.TIPS -> result?.tips?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT SessionRow.TIPS -> result?.tips?.toCurrency(currency) ?: NULL_TEXT
SessionRow.TOURNAMENT_TYPE -> this.tournamentType?.let { SessionRow.TOURNAMENT_TYPE -> this.tournamentType?.let {
TournamentType.values()[it].localizedTitle(context) TournamentType.values()[it].localizedTitle(context)
} ?: run { } ?: run {
@ -856,7 +883,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
} }
value?.let { value?.let {
return stat.format(it, CurrencyUtils.getCurrency(this.bankroll), context) return stat.format(it, currency, context)
} ?: run { } ?: run {
return TextFormat(NULL_TEXT) return TextFormat(NULL_TEXT)
} }

@ -5,11 +5,10 @@ import io.realm.Realm
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Bankroll
import net.pokeranalytics.android.model.realm.Currency import net.pokeranalytics.android.model.realm.Currency
import net.pokeranalytics.android.model.realm.Game
import net.pokeranalytics.android.model.realm.TournamentFeature import net.pokeranalytics.android.model.realm.TournamentFeature
import net.pokeranalytics.android.util.CurrencyUtils
import java.util.* import java.util.*
import net.pokeranalytics.android.model.realm.Game
import net.pokeranalytics.android.util.UserDefaults
class Seed(var context:Context) : Realm.Transaction { class Seed(var context:Context) : Realm.Transaction {
@ -32,7 +31,7 @@ class Seed(var context:Context) : Realm.Transaction {
private fun createDefaultCurrencyAndBankroll(realm: Realm) { private fun createDefaultCurrencyAndBankroll(realm: Realm) {
// Currency // Currency
val localeCurrency = CurrencyUtils.getLocaleCurrency() val localeCurrency = UserDefaults.getLocaleCurrency()
val defaultCurrency = Currency() val defaultCurrency = Currency()
defaultCurrency.code = localeCurrency.currencyCode defaultCurrency.code = localeCurrency.currencyCode
realm.insertOrUpdate(defaultCurrency) realm.insertOrUpdate(defaultCurrency)

@ -0,0 +1,33 @@
package net.pokeranalytics.android.ui.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
class ComparisonChartActivity : PokerAnalyticsActivity() {
companion object {
fun newInstance(context: Context) {
val intent = Intent(context, ComparisonChartActivity::class.java)
context.startActivity(intent)
}
/**
* Create a new instance for result
*/
fun newInstanceForResult(fragment: Fragment, requestCode: Int) {
val intent = Intent(fragment.requireContext(), ComparisonChartActivity::class.java)
fragment.startActivityForResult(intent, requestCode)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_comparison_chart)
}
}

@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.data.Entry
import kotlinx.android.synthetic.main.activity_graph.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
@ -30,9 +31,7 @@ class GraphActivity : PokerAnalyticsActivity() {
* Default constructor * Default constructor
*/ */
fun newInstance(context: Context, stat: Stat, entries: List<Entry>) { fun newInstance(context: Context, stat: Stat, entries: List<Entry>) {
parameters = GraphParameters(stat, entries)
GraphActivity.parameters = GraphParameters(stat, entries)
val intent = Intent(context, GraphActivity::class.java) val intent = Intent(context, GraphActivity::class.java)
context.startActivity(intent) context.startActivity(intent)
} }
@ -50,6 +49,9 @@ class GraphActivity : PokerAnalyticsActivity() {
*/ */
private fun initUI() { private fun initUI() {
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
val fragmentManager = supportFragmentManager val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction() val fragmentTransaction = fragmentManager.beginTransaction()
val fragment = GraphFragment() val fragment = GraphFragment()

@ -0,0 +1,80 @@
package net.pokeranalytics.android.ui.adapter
import android.content.Context
import android.util.SparseArray
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.fragment.*
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import java.lang.ref.WeakReference
/**
* Comparison Chart Pager Adapter
*/
class ComparisonChartPagerAdapter(val context: Context, fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
var weakReferences = SparseArray<WeakReference<PokerAnalyticsFragment>>()
override fun getItem(position: Int): PokerAnalyticsFragment {
return when (position) {
0 -> GraphFragment()
1 -> GraphFragment()
2 -> CalendarFragment.newInstance()
else -> HistoryFragment.newInstance()
}
}
override fun getCount(): Int {
return 3
}
override fun getPageTitle(position: Int): CharSequence? {
return when(position) {
0 -> context.getString(R.string.bar)
1 -> context.getString(R.string.line)
2-> context.getString(R.string.table)
else -> super.getPageTitle(position)
}
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
super.destroyItem(container, position, `object`)
weakReferences.remove(position)
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val fragment = super.instantiateItem(container, position) as PokerAnalyticsFragment
weakReferences.put(position, WeakReference(fragment))
return fragment
}
override fun getItemPosition(obj: Any): Int {
return when (obj) {
//CLEAN
/*
HistoryFragment::class.java -> 0
StatsFragment::class.java -> 1
SettingsFragment::class.java -> 2
*/
HistoryFragment::class.java -> 0
StatsFragment::class.java -> 1
CalendarFragment::class.java -> 2
ReportsFragment::class.java -> 3
MoreFragment::class.java -> 4
else -> -1
}
}
/**
* Return the fragment at the position key
*/
fun getFragment(key: Int): PokerAnalyticsFragment? {
if (weakReferences.get(key) != null) {
return weakReferences.get(key).get()
}
return null
}
}

@ -17,9 +17,9 @@ import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.BankrollRow import net.pokeranalytics.android.ui.view.rowrepresentable.BankrollRow
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow
import net.pokeranalytics.android.util.CurrencyUtils
import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.Preferences import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.extensions.toRate
import retrofit2.Call import retrofit2.Call
import retrofit2.Response import retrofit2.Response
import java.util.* import java.util.*
@ -96,9 +96,9 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
} }
BankrollRow.RATE -> { BankrollRow.RATE -> {
this.bankroll.currency?.rate?.let { rate -> this.bankroll.currency?.rate?.let { rate ->
CurrencyUtils.getCurrencyRateFormatter().format(rate) rate.toRate()
} ?: run { } ?: run {
CurrencyUtils.getCurrencyRateFormatter().format(1.0) 1.0.toRate()
} }
} }
else -> super.stringForRow(row) else -> super.stringForRow(row)
@ -119,7 +119,7 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
BankrollRow.RATE -> { BankrollRow.RATE -> {
this.bankroll.currency?.rate?.let { rate -> this.bankroll.currency?.rate?.let { rate ->
row.editingDescriptors(mapOf("defaultValue" to CurrencyUtils.getCurrencyRateFormatter().format(rate))) row.editingDescriptors(mapOf("defaultValue" to rate.toRate()))
} ?: run { } ?: run {
row.editingDescriptors(mapOf()) row.editingDescriptors(mapOf())
} }

@ -0,0 +1,100 @@
package net.pokeranalytics.android.ui.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.fragment_comparison_chart.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.BankrollActivity
import net.pokeranalytics.android.ui.activity.SettingsActivity
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.adapter.ComparisonChartPagerAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.MoreTabRow
class ComparisonChartFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate {
companion object {
/**
* Create new instance
*/
fun newInstance(): ComparisonChartFragment {
val fragment = ComparisonChartFragment()
val bundle = Bundle()
fragment.arguments = bundle
return fragment
}
val rowRepresentation: List<RowRepresentable> by lazy {
val rows = ArrayList<RowRepresentable>()
rows.addAll(MoreTabRow.values())
rows
}
}
private lateinit var parentActivity: PokerAnalyticsActivity
private lateinit var viewPagerAdapter: ComparisonChartPagerAdapter
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_comparison_chart, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initData()
initUI()
}
// Rows
override fun adapterRows(): List<RowRepresentable>? {
return rowRepresentation
}
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
super.onRowSelected(position, row, fromAction)
when(row) {
MoreTabRow.BANKROLL -> BankrollActivity.newInstance(requireContext())
MoreTabRow.SETTINGS -> SettingsActivity.newInstance(requireContext())
}
}
// Business
/**
* Init data
*/
private fun initData() {
}
/**
* Init UI
*/
private fun initUI() {
parentActivity = activity as PokerAnalyticsActivity
toolbar.title = ""
parentActivity.setSupportActionBar(toolbar)
parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
setHasOptionsMenu(true)
toolbar.title = "Comparison chart"
viewPagerAdapter = ComparisonChartPagerAdapter(requireContext(), parentActivity.supportFragmentManager)
viewPager.adapter = viewPagerAdapter
tabs.setupWithViewPager(viewPager)
}
}

@ -32,8 +32,8 @@ class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener {
private lateinit var parentActivity: PokerAnalyticsActivity private lateinit var parentActivity: PokerAnalyticsActivity
lateinit var stat: Stat private var stat: Stat = Stat.NETRESULT
lateinit var entries: List<Entry> private var entries: List<Entry> = ArrayList()
lateinit var legendView: LegendView lateinit var legendView: LegendView
lateinit var chartView: BarLineChartBase<*> lateinit var chartView: BarLineChartBase<*>
@ -62,20 +62,12 @@ class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener {
private fun initUI() { private fun initUI() {
parentActivity = activity as PokerAnalyticsActivity parentActivity = activity as PokerAnalyticsActivity
parentActivity.title = stat.localizedTitle(requireContext())
this.legendView = LegendView(requireContext()) this.legendView = LegendView(requireContext())
this.legendContainer.addView(this.legendView) this.legendContainer.addView(this.legendView)
this.legendView.prepareWithStat(this.stat, this.entries.size) this.legendView.prepareWithStat(this.stat, this.entries.size)
// Avoid a bug during setting the title
toolbar.title = ""
parentActivity.setSupportActionBar(toolbar)
parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
setHasOptionsMenu(true)
toolbar.title = stat.localizedTitle(requireContext())
val dataSet = LineDataSet(this.entries, this.stat.name) val dataSet = LineDataSet(this.entries, this.stat.name)
val colors = arrayOf(R.color.green_light).toIntArray() val colors = arrayOf(R.color.green_light).toIntArray()
dataSet.setColors(colors, context) dataSet.setColors(colors, context)
@ -110,6 +102,8 @@ class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener {
this.chipGroup.addView(chip) this.chipGroup.addView(chip)
} }
this.chipGroup.check(this.stat.aggregationTypes.first().ordinal)
this.chipGroup.setOnCheckedChangeListener(object : ChipGroupExtension.SingleSelectionOnCheckedListener() { this.chipGroup.setOnCheckedChangeListener(object : ChipGroupExtension.SingleSelectionOnCheckedListener() {
override fun onCheckedChanged(group: ChipGroup, checkedId: Int) { override fun onCheckedChanged(group: ChipGroup, checkedId: Int) {
super.onCheckedChanged(group, checkedId) super.onCheckedChanged(group, checkedId)
@ -117,7 +111,6 @@ class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener {
} }
}) })
this.chipGroup.check(this.stat.aggregationTypes.first().ordinal)
} }
// OnChartValueSelectedListener // OnChartValueSelectedListener

@ -7,6 +7,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_stats.* import kotlinx.android.synthetic.main.fragment_stats.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.ComparisonChartActivity
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
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
@ -56,6 +57,11 @@ class ReportsFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSour
return rowRepresentation return rowRepresentation
} }
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
super.onRowSelected(position, row, fromAction)
ComparisonChartActivity.newInstance(requireContext())
}
// Business // Business

@ -27,7 +27,6 @@ import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableDiffCallback import net.pokeranalytics.android.ui.view.RowRepresentableDiffCallback
import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager
import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow
import net.pokeranalytics.android.util.CurrencyUtils
import java.util.* import java.util.*
@ -104,9 +103,9 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate {
} }
SessionRow.BANKROLL -> { SessionRow.BANKROLL -> {
BottomSheetFragment.create(fragmentManager, row, this, data, false, CurrencyUtils.getCurrency(currentSession.bankroll)) BottomSheetFragment.create(fragmentManager, row, this, data, false, currentSession.currency)
} }
else -> BottomSheetFragment.create(fragmentManager, row, this, data, currentCurrency = CurrencyUtils.getCurrency(currentSession.bankroll)) else -> BottomSheetFragment.create(fragmentManager, row, this, data, currentCurrency = currentSession.currency)
} }
} }

@ -7,9 +7,11 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.Realm
import kotlinx.android.synthetic.main.fragment_settings.* import kotlinx.android.synthetic.main.fragment_settings.*
import net.pokeranalytics.android.BuildConfig import net.pokeranalytics.android.BuildConfig
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Bankroll
import net.pokeranalytics.android.ui.activity.CurrenciesActivity import net.pokeranalytics.android.ui.activity.CurrenciesActivity
import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.DataListActivity
import net.pokeranalytics.android.ui.activity.GDPRActivity import net.pokeranalytics.android.ui.activity.GDPRActivity
@ -22,6 +24,7 @@ import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SettingRow import net.pokeranalytics.android.ui.view.rowrepresentable.SettingRow
import net.pokeranalytics.android.util.Preferences import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.URL import net.pokeranalytics.android.util.URL
import net.pokeranalytics.android.util.UserDefaults
import net.pokeranalytics.android.util.extensions.openContactMail import net.pokeranalytics.android.util.extensions.openContactMail
import net.pokeranalytics.android.util.extensions.openPlayStorePage import net.pokeranalytics.android.util.extensions.openPlayStorePage
import net.pokeranalytics.android.util.extensions.openUrl import net.pokeranalytics.android.util.extensions.openUrl
@ -30,7 +33,6 @@ import java.util.*
class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, StaticRowRepresentableDataSource { class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, StaticRowRepresentableDataSource {
private lateinit var parentActivity: PokerAnalyticsActivity
companion object { companion object {
@ -53,15 +55,8 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta
const val REQUEST_CODE_CURRENCY: Int = 100 const val REQUEST_CODE_CURRENCY: Int = 100
} }
override fun stringForRow(row: RowRepresentable): String {
return when (row) {
SettingRow.VERSION -> BuildConfig.VERSION_NAME + if (BuildConfig.DEBUG) " (${BuildConfig.VERSION_CODE}) DEBUG" else ""
SettingRow.CURRENCY -> Currency.getInstance(Preferences.getCurrencyLocale(this.parentActivity)).symbol
else -> ""
}
}
private lateinit var settingsAdapterRow: RowRepresentableAdapter private lateinit var settingsAdapterRow: RowRepresentableAdapter
private lateinit var parentActivity: PokerAnalyticsActivity
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -78,6 +73,13 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta
if (requestCode == REQUEST_CODE_CURRENCY && resultCode == Activity.RESULT_OK) { if (requestCode == REQUEST_CODE_CURRENCY && resultCode == Activity.RESULT_OK) {
data?.let { data?.let {
Preferences.setCurrencyCode(data.getStringExtra(CurrenciesFragment.INTENT_CURRENCY_CODE), requireContext()) Preferences.setCurrencyCode(data.getStringExtra(CurrenciesFragment.INTENT_CURRENCY_CODE), requireContext())
val realm = Realm.getDefaultInstance()
realm.executeTransaction {
it.where(Bankroll::class.java).isNull("currency.code").findAll().forEach { bankroll ->
bankroll.currencyCodeHasBeenUpdated()
}
}
realm.close()
settingsAdapterRow.refreshRow(SettingRow.CURRENCY) settingsAdapterRow.refreshRow(SettingRow.CURRENCY)
} }
} }
@ -87,6 +89,14 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta
return rowRepresentation return rowRepresentation
} }
override fun stringForRow(row: RowRepresentable): String {
return when (row) {
SettingRow.VERSION -> BuildConfig.VERSION_NAME + if (BuildConfig.DEBUG) " (${BuildConfig.VERSION_CODE}) DEBUG" else ""
SettingRow.CURRENCY -> UserDefaults.currency.symbol
else -> ""
}
}
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
when (row) { when (row) {

@ -16,7 +16,6 @@ import net.pokeranalytics.android.model.extensions.SessionState
import net.pokeranalytics.android.model.extensions.getState import net.pokeranalytics.android.model.extensions.getState
import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.view.fields.setTextFormat import net.pokeranalytics.android.ui.view.fields.setTextFormat
import net.pokeranalytics.android.util.CurrencyUtils
import net.pokeranalytics.android.util.extensions.getDayNumber import net.pokeranalytics.android.util.extensions.getDayNumber
import net.pokeranalytics.android.util.extensions.getShortDayName import net.pokeranalytics.android.util.extensions.getShortDayName
import net.pokeranalytics.android.util.extensions.shortTime import net.pokeranalytics.android.util.extensions.shortTime
@ -69,7 +68,7 @@ class SessionRowView : FrameLayout {
if (session.isTournament()) { if (session.isTournament()) {
session.tournamentEntryFee?.let { session.tournamentEntryFee?.let {
parameters.add(it.toCurrency(CurrencyUtils.getCurrency(session.bankroll))) parameters.add(it.toCurrency(session.currency))
} }
session.tournamentName?.let { session.tournamentName?.let {
@ -86,7 +85,7 @@ class SessionRowView : FrameLayout {
} }
} else { } else {
if (session.cgSmallBlind != null && session.cgBigBlind != null) { if (session.cgSmallBlind != null && session.cgBigBlind != null) {
parameters.add(session.getBlinds()) parameters.add(session.getFormattedBlinds())
} }
session.game?.let { session.game?.let {
parameters.add(session.getFormattedGame()) parameters.add(session.getFormattedGame())
@ -150,7 +149,7 @@ class SessionRowView : FrameLayout {
rowHistorySession.infoTitle.isVisible = false rowHistorySession.infoTitle.isVisible = false
val result = session.result?.net ?: 0.0 val result = session.result?.net ?: 0.0
val formattedStat = ComputedStat(Stat.NETRESULT, result, currency = CurrencyUtils.getCurrency(session.bankroll)).format(context) val formattedStat = ComputedStat(Stat.NETRESULT, result, currency = session.currency).format(context)
rowHistorySession.gameResult.setTextFormat(formattedStat, context) rowHistorySession.gameResult.setTextFormat(formattedStat, context)
// rowHistorySession.gameResult.setTextColor(formattedStat.getColor(context)) // rowHistorySession.gameResult.setTextColor(formattedStat.getColor(context))
// rowHistorySession.gameResult.text = formattedStat.text // rowHistorySession.gameResult.text = formattedStat.text

@ -54,7 +54,7 @@ enum class FilterCategoryRow(override val resId: Int?, override val viewType: In
BANKROLL BANKROLL
) )
CASH -> arrayListOf( CASH -> arrayListOf(
BLINDS, BLIND,
CASH_RE_BUY_COUNT CASH_RE_BUY_COUNT
) )
TOURNAMENT -> arrayListOf( TOURNAMENT -> arrayListOf(

@ -11,10 +11,8 @@ import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheet
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.util.CurrencyUtils import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.UserDefaults
import net.pokeranalytics.android.util.extensions.formatted
import net.pokeranalytics.android.util.extensions.round
import java.text.DateFormatSymbols import java.text.DateFormatSymbols
import java.util.* import java.util.*
@ -105,14 +103,7 @@ sealed class FilterElementRow : RowRepresentable {
data class Month(val month: Int) : SingleValueFilterElementRow(month) data class Month(val month: Int) : SingleValueFilterElementRow(month)
data class Day(val day: Int) : SingleValueFilterElementRow(day) data class Day(val day: Int) : SingleValueFilterElementRow(day)
data class Blind(var sb: Double? = null, var bb: Double? = null, var code: String? = null) : FilterElementRow() { data class Blind(val blind: String, val hasDefaultCurrency: Boolean) : StringFilterElementRow(blind)
val name: String
get() {
val currencyCode = code ?: CurrencyUtils.getLocaleCurrency().currencyCode
val currencySymbol = Currency.getInstance(currencyCode).symbol
return if (sb == null) NULL_TEXT else "$currencySymbol ${sb?.formatted()}/${bb?.round()}"
}
}
//TODO: Refactor? //TODO: Refactor?
data class PastDays(var lastDays: Int = 0) : SingleValueFilterElementRow(lastDays) { data class PastDays(var lastDays: Int = 0) : SingleValueFilterElementRow(lastDays) {
@ -155,7 +146,7 @@ sealed class FilterElementRow : RowRepresentable {
return when (this) { return when (this) {
is Cash -> QueryCondition.CASH is Cash -> QueryCondition.CASH
is Tournament -> QueryCondition.TOURNAMENT is Tournament -> QueryCondition.TOURNAMENT
is Blind -> QueryCondition.BLINDS is Blind -> QueryCondition.BLIND
is From -> QueryCondition.STARTED_FROM_DATE is From -> QueryCondition.STARTED_FROM_DATE
is To -> QueryCondition.ENDED_TO_DATE is To -> QueryCondition.ENDED_TO_DATE
is FromTime -> QueryCondition.STARTED_FROM_TIME is FromTime -> QueryCondition.STARTED_FROM_TIME
@ -308,7 +299,7 @@ sealed class FilterElementRow : RowRepresentable {
} }
is DataFilterElementRow -> this.name is DataFilterElementRow -> this.name
is StaticDataFilterElementRow -> this.name is StaticDataFilterElementRow -> this.name
is Blind -> this.name is Blind -> this.blind
else -> super.getDisplayName() else -> super.getDisplayName()
} }
} }

@ -30,7 +30,7 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable {
SESSION_DURATION(net.pokeranalytics.android.R.string.session_duration), SESSION_DURATION(net.pokeranalytics.android.R.string.session_duration),
RANGE(net.pokeranalytics.android.R.string.hour_slot), RANGE(net.pokeranalytics.android.R.string.hour_slot),
SESSIONS(R.string.sessions), SESSIONS(R.string.sessions),
BLINDS(net.pokeranalytics.android.R.string.blinds), BLIND(net.pokeranalytics.android.R.string.blinds),
CASH_RE_BUY_COUNT(net.pokeranalytics.android.R.string.rebuy_count), CASH_RE_BUY_COUNT(net.pokeranalytics.android.R.string.rebuy_count),
TOURNAMENT_TYPE(net.pokeranalytics.android.R.string.tournament_types), TOURNAMENT_TYPE(net.pokeranalytics.android.R.string.tournament_types),
TOURNAMENT_NAME(net.pokeranalytics.android.R.string.tournament_name), TOURNAMENT_NAME(net.pokeranalytics.android.R.string.tournament_name),
@ -160,36 +160,15 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable {
SESSIONS -> arrayListOf(LastGames(0), LastSessions(0)) SESSIONS -> arrayListOf(LastGames(0), LastSessions(0))
// Cash // Cash
BLINDS -> { BLIND -> {
val blinds = arrayListOf<Blind>()
// TODO: Improve the way we get the blinds distinctly
val blinds = arrayListOf<FilterElementRow.Blind>()
val realm = Realm.getDefaultInstance() val realm = Realm.getDefaultInstance()
val sessions = realm.where<Session>().distinct("blind", "bankroll.currency.code").findAll().sort("cgSmallBlind", Sort.ASCENDING).map {
realm.where<Session>().isNotNull("cgSmallBlind").isNotNull("cgBigBlind").findAll() it.blinds?.let { stake ->
.sort("cgSmallBlind", Sort.ASCENDING) blinds.add(Blind(stake, it.hasDefaultCurrency))
val distinctBlinds: ArrayList<Session> = ArrayList()
val blindsHashMap: ArrayList<String> = ArrayList()
sessions.forEach {
if (!blindsHashMap.contains(it.getBlinds())) {
blindsHashMap.add(it.getBlinds())
distinctBlinds.add(it)
} }
} }
distinctBlinds.forEach { session ->
blinds.add(
Blind(
session.cgSmallBlind,
session.cgBigBlind,
session.bankroll?.currency?.code
)
)
session.getBlinds()
}
realm.close() realm.close()
blinds blinds
} }
CASH_RE_BUY_COUNT -> arrayListOf( CASH_RE_BUY_COUNT -> arrayListOf(

@ -1,64 +0,0 @@
package net.pokeranalytics.android.util
import android.content.Context
import net.pokeranalytics.android.model.realm.Bankroll
import java.text.NumberFormat
import java.util.*
class CurrencyUtils {
companion object {
/**
* return the currency associated with this bankroll
*/
fun getCurrency(bankroll: Bankroll? = null) : Currency {
val currencyCode = bankroll?.currency?.code ?: CurrencyUtils.getLocaleCurrency().currencyCode
return Currency.getInstance(currencyCode)
}
/**
* Get a currency formatter
*/
fun getCurrencyFormatter(context: Context, currency: Currency? = null) : NumberFormat {
val currencyFormatter = NumberFormat.getCurrencyInstance(Preferences.getCurrencyLocale(context))
currency?.let {
currencyFormatter.currency = it
}
currencyFormatter.minimumFractionDigits = 0
currencyFormatter.maximumFractionDigits = 2
return currencyFormatter
}
/**
* Get a currency rate formatter
*/
fun getCurrencyRateFormatter() : NumberFormat {
val currencyFormatter = NumberFormat.getInstance()
currencyFormatter.minimumFractionDigits = 0
currencyFormatter.maximumFractionDigits = 6
return currencyFormatter
}
/**
* Return the locale currency, or en_US if there
*/
fun getLocaleCurrency() : Currency {
return try {
Currency.getInstance(Locale.getDefault())
} catch (ex: Exception) {
when (Locale.getDefault().language) {
"en" -> Currency.getInstance(Locale("en", "US"))
"fr" -> Currency.getInstance(Locale("fr", "FR"))
"es" -> Currency.getInstance(Locale("es", "ES"))
"de" -> Currency.getInstance(Locale("de", "DE"))
"ja" -> Currency.getInstance(Locale("ja", "JP"))
"zh" -> Currency.getInstance(Locale("zh", "CN"))
else -> Currency.getInstance(Locale("en", "US"))
}
}
}
}
}

@ -16,8 +16,6 @@ class Preferences {
companion object { companion object {
var currencyLocale : Locale? = null
fun setString(key: Keys, value: String, context: Context) { fun setString(key: Keys, value: String, context: Context) {
val preferences = PreferenceManager.getDefaultSharedPreferences(context) val preferences = PreferenceManager.getDefaultSharedPreferences(context)
val editor = preferences.edit() val editor = preferences.edit()
@ -43,21 +41,16 @@ class Preferences {
} }
fun setCurrencyCode(currencyCode: String, context: Context) { fun setCurrencyCode(currencyCode: String, context: Context) {
Preferences.setString(Keys.CURRENCY_CODE, currencyCode, context) setString(Keys.CURRENCY_CODE, currencyCode, context)
currencyLocale = null UserDefaults.setCurrencyValues(context)
} }
private fun getCurrencyCode(context: Context) : String? { private fun getCurrencyCode(context: Context) : String? {
return Preferences.getString(Keys.CURRENCY_CODE, context) return getString(Keys.CURRENCY_CODE, context)
} }
fun getCurrencyLocale(context : Context) : Locale { fun getCurrencyLocale(context : Context) : Locale? {
getCurrencyCode(context)?.let { currencyCode ->
currencyLocale?. let {
return it
}
Preferences.getCurrencyCode(context)?.let { currencyCode ->
Locale.getAvailableLocales().filter{ Locale.getAvailableLocales().filter{
try { try {
Currency.getInstance(it).currencyCode == currencyCode Currency.getInstance(it).currencyCode == currencyCode
@ -65,22 +58,87 @@ class Preferences {
false false
} }
}.first().let { }.first().let {
currencyLocale = it
return it return it
} }
} }
currencyLocale = Locale.getDefault() return null
return currencyLocale!! }
fun getDefaultCurrency(context: Context) : Currency? {
getCurrencyLocale(context)?.let {
return Currency.getInstance(it)
}
return null
} }
fun setStopShowingDisclaimer(context: Context) { fun setStopShowingDisclaimer(context: Context) {
Preferences.setBoolean(Keys.STOP_SHOWING_DISCLAIMER, true, context) setBoolean(Keys.STOP_SHOWING_DISCLAIMER, true, context)
} }
fun shouldShowDisclaimer(context: Context) : Boolean { fun shouldShowDisclaimer(context: Context) : Boolean {
return !Preferences.getBoolean(Keys.STOP_SHOWING_DISCLAIMER, context) return !getBoolean(Keys.STOP_SHOWING_DISCLAIMER, context)
}
}
}
class UserDefaults private constructor(context: Context) {
init {
setCurrencyValues(context)
} }
companion object : SingletonHolder<UserDefaults, Context>(::UserDefaults) {
lateinit var currency : Currency
lateinit var currencyLocale : Locale
fun setCurrencyValues(context: Context) {
currency = Preferences.getDefaultCurrency(context) ?: getLocaleCurrency()
currencyLocale = Preferences.getCurrencyLocale(context) ?: Locale.getDefault()
}
/**
* Return the locale currency, or en_US if there
*/
fun getLocaleCurrency() : Currency {
return try {
Currency.getInstance(Locale.getDefault())
} catch (ex: Exception) {
when (Locale.getDefault().language) {
"en" -> Currency.getInstance(Locale("en", "US"))
"fr" -> Currency.getInstance(Locale("fr", "FR"))
"es" -> Currency.getInstance(Locale("es", "ES"))
"de" -> Currency.getInstance(Locale("de", "DE"))
"ja" -> Currency.getInstance(Locale("ja", "JP"))
"zh" -> Currency.getInstance(Locale("zh", "CN"))
else -> Currency.getInstance(Locale("en", "US"))
}
}
}
}
} }
open class SingletonHolder<out T, in A>(creator: (A) -> T) {
private var creator: ((A) -> T)? = creator
@Volatile private var instance: T? = null
fun init(context: A): T {
val i = instance
if (i != null) {
return i
}
return synchronized(this) {
val i2 = instance
if (i2 != null) {
i2
} else {
val created = creator!!(context)
instance = created
creator = null
created
}
}
}
} }

@ -2,6 +2,7 @@ package net.pokeranalytics.android.util.extensions
import android.content.Context import android.content.Context
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.util.UserDefaults
import java.text.DecimalFormat import java.text.DecimalFormat
import java.text.NumberFormat import java.text.NumberFormat
import java.util.* import java.util.*
@ -23,7 +24,7 @@ fun Double.formatted(): String {
fun Double.toCurrency(currency: Currency? = null): String { fun Double.toCurrency(currency: Currency? = null): String {
val currencyFormatter = NumberFormat.getCurrencyInstance() val currencyFormatter = NumberFormat.getCurrencyInstance(UserDefaults.currencyLocale)
currency?.let { currency?.let {
currencyFormatter.currency = currency currencyFormatter.currency = currency
} }
@ -33,6 +34,14 @@ fun Double.toCurrency(currency: Currency? = null): String {
return currencyFormatter.format(this) return currencyFormatter.format(this)
} }
fun Double.toRate(): String {
val currencyFormatter = NumberFormat.getInstance()
currencyFormatter.minimumFractionDigits = 0
currencyFormatter.maximumFractionDigits = 6
return currencyFormatter.format(this)
}
fun Double.formattedHourlyDuration() : String { fun Double.formattedHourlyDuration() : String {
return (this * 1000 * 3600).toLong().toMinutes() return (this * 1000 * 3600).toLong().toMinutes()
} }

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<fragment
android:id="@+id/comparisonChartFragment"
android:name="net.pokeranalytics.android.ui.fragment.ComparisonChartFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="@layout/fragment_comparison_chart" />
</LinearLayout>

@ -1,8 +1,26 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
</FrameLayout> <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:title="@string/app_name" />
<FrameLayout
android:id="@+id/container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/PokerAnalyticsTheme.Toolbar.Session"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:titleTextColor="@color/white"
tools:title="Poker Analytics" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bar" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/line" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/table" />
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appBar" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -5,22 +5,13 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:title="@string/app_name" />
<FrameLayout <FrameLayout
android:id="@+id/legendContainer" android:id="@+id/legendContainer"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar" /> app:layout_constraintTop_toTopOf="parent" />
<FrameLayout <FrameLayout
android:id="@+id/chartContainer" android:id="@+id/chartContainer"

@ -7,6 +7,7 @@
<string name="minute">Minute</string> <string name="minute">Minute</string>
<string name="more">More</string> <string name="more">More</string>
<string name="variant">Variant</string> <string name="variant">Variant</string>
<string name="line">Line</string>
<!--<string name="session_missing_end_date">Please set the end date for the session</string>--> <!--<string name="session_missing_end_date">Please set the end date for the session</string>-->
<!--<string name="default_error_message">Sorry, something went wrong...please contact us!</string>--> <!--<string name="default_error_message">Sorry, something went wrong...please contact us!</string>-->

@ -19,6 +19,7 @@
<item name="android:textViewStyle">@style/PokerAnalyticsTheme.TextView</item> <item name="android:textViewStyle">@style/PokerAnalyticsTheme.TextView</item>
<item name="alertDialogTheme">@style/PokerAnalyticsTheme.AlertDialog</item> <item name="alertDialogTheme">@style/PokerAnalyticsTheme.AlertDialog</item>
<item name="chipStyle">@style/PokerAnalyticsTheme.Chip</item> <item name="chipStyle">@style/PokerAnalyticsTheme.Chip</item>
<item name="tabStyle">@style/PokerAnalyticsTheme.TabLayout</item>
</style> </style>
@ -179,6 +180,14 @@
<item name="android:fontFamily">@font/roboto</item> <item name="android:fontFamily">@font/roboto</item>
</style> </style>
<!-- Tabs -->
<style name="PokerAnalyticsTheme.TabLayout" parent="Widget.MaterialComponents.TabLayout">
<item name="android:background">@color/colorPrimary</item>
<item name="tabTextColor">@color/gray_light</item>
<item name="tabSelectedTextColor">@color/green</item>
<item name="tabRippleColor">@color/green_transparent</item>
</style>
<!-- Session Row --> <!-- Session Row -->

Loading…
Cancel
Save