merge fix conflicts

feature/top10
Razmig Sarkissian 7 years ago
commit b0babe5766
  1. 3
      app/proguard-rules.pro
  2. 2
      app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt
  3. 10
      app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt
  4. 48
      app/src/main/java/net/pokeranalytics/android/calculus/Report.kt
  5. 47
      app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt
  6. 0
      app/src/main/java/net/pokeranalytics/android/calculus/TextFormat.kt
  7. 3
      app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt
  8. 7
      app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt
  9. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/FilterCondition.kt
  10. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/ReportSetup.kt
  11. 20
      app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt
  12. 2
      app/src/main/java/net/pokeranalytics/android/ui/activity/GraphActivity.kt
  13. 7
      app/src/main/java/net/pokeranalytics/android/ui/fragment/FilterDetailsFragment.kt
  14. 70
      app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt
  15. 32
      app/src/main/java/net/pokeranalytics/android/ui/fragment/StatsFragment.kt
  16. 28
      app/src/main/java/net/pokeranalytics/android/ui/graph/GraphExtensions.kt
  17. 7
      app/src/main/java/net/pokeranalytics/android/ui/helpers/DateTimePickerManager.kt
  18. 69
      app/src/main/java/net/pokeranalytics/android/ui/view/LegendView.kt
  19. 37
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt
  20. 26
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt
  21. 21
      app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt
  22. 3
      app/src/main/res/layout/activity_graph.xml
  23. 59
      app/src/main/res/layout/fragment_evograph.xml
  24. 25
      app/src/main/res/layout/fragment_graph.xml
  25. 94
      app/src/main/res/layout/layout_legend_default.xml
  26. 2
      app/src/main/res/values/colors.xml
  27. 59
      app/src/main/res/values/styles.xml

@ -58,3 +58,6 @@
# Guava # Guava
-dontwarn com.google.j2objc.annotations.** -dontwarn com.google.j2objc.annotations.**
-keep class com.google.j2objc.annotations.** { *; } -keep class com.google.j2objc.annotations.** { *; }
# Enum
-optimizations !class/unboxing/enum

@ -27,7 +27,7 @@ class PokerAnalyticsApplication : Application() {
Realm.init(this) Realm.init(this)
val realmConfiguration = RealmConfiguration.Builder() val realmConfiguration = RealmConfiguration.Builder()
.name(Realm.DEFAULT_REALM_NAME) .name(Realm.DEFAULT_REALM_NAME)
.schemaVersion(2) .schemaVersion(3)
.migration(PokerAnalyticsMigration()) .migration(PokerAnalyticsMigration())
.initialData(Seed(this)) .initialData(Seed(this))
.build() .build()

@ -60,7 +60,7 @@ class Calculator {
companion object { companion object {
fun computeStatsWithFilters(realm: Realm, filters: List<Filter>, options: Options): List<ComputedResults> { fun computeStatsWithFilters(realm: Realm, filters: List<Filter>, options: Options): Report {
var computableGroups: MutableList<ComputableGroup> = mutableListOf() var computableGroups: MutableList<ComputableGroup> = mutableListOf()
filters.forEach { filter -> filters.forEach { filter ->
@ -75,9 +75,9 @@ class Calculator {
/** /**
* Computes all stats for list of Session sessionGroup * Computes all stats for list of Session sessionGroup
*/ */
fun computeGroups(realm: Realm, groups: List<ComputableGroup>, options: Options): List<ComputedResults> { fun computeGroups(realm: Realm, groups: List<ComputableGroup>, options: Options): Report {
val computedResults = mutableListOf<ComputedResults>() val report = Report()
groups.forEach { group -> groups.forEach { group ->
val s = Date() val s = Date()
@ -96,7 +96,7 @@ class Calculator {
} }
results.finalize(options) // later treatment, such as evolution numericValues sorting results.finalize(options) // later treatment, such as evolution numericValues sorting
computedResults.add(results) report.addResults(results)
val e = Date() val e = Date()
val duration = (e.time - s.time) / 1000.0 val duration = (e.time - s.time) / 1000.0
@ -104,7 +104,7 @@ class Calculator {
} }
return computedResults return report
} }
/** /**

@ -10,6 +10,54 @@ import net.pokeranalytics.android.model.realm.ComputableResult
import net.pokeranalytics.android.model.realm.Filter import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.model.realm.SessionSet import net.pokeranalytics.android.model.realm.SessionSet
/**
* The class returned after performing calculation in the Calculator object
*/
class Report() {
private var _results: MutableList<ComputedResults> = mutableListOf()
val results: List<ComputedResults> = this._results
// private var groups: MutableList<ComputableGroup> = mutableListOf()
//
// var options: Calculator.Options = options
//
// fun addGroup(group: ComputableGroup) {
// this.groups.add(group)
// }
//
// fun addGroups(groups: Collection<ComputableGroup>) {
// this.groups.addAll(groups)
// }
fun addResults(result: ComputedResults) {
this._results.add(result)
}
fun barEntries(stat: Stat): List<Entry> {
val entries = mutableListOf<Entry>()
this._results.forEachIndexed { index, results ->
val cs = results.computedStat(stat)
cs?.let { computedStat ->
entries.add(Entry(index.toFloat(), computedStat.value.toFloat(), results.group))
}
}
return entries
}
fun multiLineEntries(stat: Stat): List<List<Entry>> {
val entries = mutableListOf<List<Entry>>()
this._results.forEach { result ->
val entryList = result.singleLineEntries(stat)
entries.add(entryList)
}
return entries
}
}
/** /**
* A sessionGroup of computable items identified by a name * A sessionGroup of computable items identified by a name
*/ */

@ -23,6 +23,28 @@ interface StatBase : RealmModel {
} }
enum class GraphType {
LINE,
BAR,
}
enum class AggregationType {
SESSION,
MONTH,
YEAR,
DURATION;
val resId: Int
get() {
return when (this) {
SESSION -> R.string.session
MONTH -> R.string.month
YEAR -> R.string.year
DURATION -> R.string.duration
}
}
}
/** /**
* An enum representing all the types of Session statistics * An enum representing all the types of Session statistics
*/ */
@ -150,7 +172,7 @@ enum class Stat(var underlyingClass: Class<out Timed>? = null) : RowRepresentabl
fun cumulativeLabelResId(context: Context) : String { fun cumulativeLabelResId(context: Context) : String {
val resId = when (this) { val resId = when (this) {
AVERAGE, AVERAGE_DURATION, NETRESULT, NET_BB_PER_100_HANDS, AVERAGE, AVERAGE_DURATION, NET_BB_PER_100_HANDS,
HOURLY_RATE_BB, AVERAGE_NET_BB, ROI, WIN_RATIO, HOURLY_RATE -> R.string.average HOURLY_RATE_BB, AVERAGE_NET_BB, ROI, WIN_RATIO, HOURLY_RATE -> R.string.average
NETRESULT, DURATION -> R.string.total NETRESULT, DURATION -> R.string.total
STANDARD_DEVIATION -> R.string.net_result STANDARD_DEVIATION -> R.string.net_result
@ -165,6 +187,22 @@ enum class Stat(var underlyingClass: Class<out Timed>? = null) : RowRepresentabl
} }
} }
val graphType: GraphType
get() {
return when (this) {
NUMBER_OF_SETS, NUMBER_OF_GAMES -> GraphType.BAR
else -> GraphType.LINE
}
}
val aggregationTypes: List<AggregationType>
get() {
return when (this) {
NETRESULT -> listOf(AggregationType.SESSION, AggregationType.MONTH, AggregationType.YEAR, AggregationType.DURATION)
else -> listOf(AggregationType.SESSION, AggregationType.MONTH, AggregationType.YEAR, AggregationType.DURATION)
}
}
override val viewType: Int = RowViewType.TITLE_VALUE.ordinal override val viewType: Int = RowViewType.TITLE_VALUE.ordinal
} }
@ -191,11 +229,4 @@ class ComputedStat(var stat: Stat, var value: Double, var currency: Currency? =
return this.stat.format(this.value, this.currency, context) return this.stat.format(this.value, this.currency, context)
} }
/**
* Returns a TextFormat instance for an evolution value located at the specified [index]
*/
fun evolutionValueFormat(index: Int): TextFormat {
return TextFormat("undef ${index}")
}
} }

@ -4,6 +4,7 @@ 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.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.*
@ -71,6 +72,8 @@ enum class QueryCondition(var operator: Operator? = null) {
PAST_DAYS, PAST_DAYS,
MORE_THAN_DURATION(Operator.MORE), MORE_THAN_DURATION(Operator.MORE),
LESS_THAN_DURATION(Operator.LESS), LESS_THAN_DURATION(Operator.LESS),
STARTED_FROM_TIME,
ENDED_TO_TIME,
COMMENT, COMMENT,

@ -46,6 +46,13 @@ class PokerAnalyticsMigration : RealmMigration {
currentVersion++ currentVersion++
} }
// Migrate to version 2
if (currentVersion == 2) {
Timber.d("*** Running migration ${currentVersion + 1}")
schema.rename("Report", "ReportSetup")
currentVersion++
}
} }
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {

@ -115,7 +115,7 @@ open class FilterCondition() : RealmObject() {
*/ */
fun getFilterConditionValue(filterElementRow: FilterElementRow): Any? { fun getFilterConditionValue(filterElementRow: FilterElementRow): Any? {
return when (filterElementRow) { return when (filterElementRow) {
is From, is To -> dateValue //TODO: Probably change by 'date' (doesn't work now because the value isn't correctly saved is DateFilterElementRow -> date
is PastDays -> values is PastDays -> values
else -> throw PokerAnalyticsException.FilterElementTypeMissing(filterElementRow) else -> throw PokerAnalyticsException.FilterElementTypeMissing(filterElementRow)
} }

@ -11,7 +11,7 @@ enum class ReportDisplay {
MAP MAP
} }
open class Report : RealmObject() { open class ReportSetup : RealmObject() {
@PrimaryKey @PrimaryKey
var id = UUID.randomUUID().toString() var id = UUID.randomUUID().toString()

@ -3,9 +3,14 @@ package net.pokeranalytics.android.model.utils
import android.content.Context import android.content.Context
import io.realm.Realm import io.realm.Realm
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.R import net.pokeranalytics.android.model.realm.Bankroll
import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.model.realm.Currency import net.pokeranalytics.android.model.realm.Currency
<<<<<<< HEAD
=======
import net.pokeranalytics.android.model.realm.Game
import net.pokeranalytics.android.model.realm.TournamentFeature
import net.pokeranalytics.android.util.CurrencyUtils
>>>>>>> 7fce9661594eb0faba91337d78c6cc1e880e49a1
import java.util.* import java.util.*
@ -19,7 +24,7 @@ class Seed(var context:Context) : Realm.Transaction {
} }
private fun createDefaultTournamentFeatures(realm: Realm) { private fun createDefaultTournamentFeatures(realm: Realm) {
context.resources.getStringArray(R.array.seed_tournament_features).forEach { context.resources.getStringArray(net.pokeranalytics.android.R.array.seed_tournament_features).forEach {
val tournamentFeature = TournamentFeature() val tournamentFeature = TournamentFeature()
tournamentFeature.id = UUID.randomUUID().toString() tournamentFeature.id = UUID.randomUUID().toString()
tournamentFeature.name = it tournamentFeature.name = it
@ -37,8 +42,13 @@ class Seed(var context:Context) : Realm.Transaction {
} }
private fun createDefaultCurrencyAndBankroll(realm: Realm) { private fun createDefaultCurrencyAndBankroll(realm: Realm) {
// Currency // Currency
<<<<<<< HEAD
val localeCurrency = localeCurrency val localeCurrency = localeCurrency
=======
val localeCurrency = CurrencyUtils.getLocaleCurrency()
>>>>>>> 7fce9661594eb0faba91337d78c6cc1e880e49a1
val defaultCurrency = Currency() val defaultCurrency = Currency()
defaultCurrency.code = localeCurrency.currencyCode defaultCurrency.code = localeCurrency.currencyCode
realm.insertOrUpdate(defaultCurrency) realm.insertOrUpdate(defaultCurrency)
@ -52,8 +62,8 @@ class Seed(var context:Context) : Realm.Transaction {
} }
private fun createDefaultGames(realm: Realm) { private fun createDefaultGames(realm: Realm) {
val gamesName = context.resources.getStringArray(R.array.seed_games) val gamesName = context.resources.getStringArray(net.pokeranalytics.android.R.array.seed_games)
val gamesShortName = context.resources.getStringArray(R.array.seed_games_short_name) val gamesShortName = context.resources.getStringArray(net.pokeranalytics.android.R.array.seed_games_short_name)
for ((index, name) in gamesName.withIndex()) { for ((index, name) in gamesName.withIndex()) {
val game = Game() val game = Game()
game.id = UUID.randomUUID().toString() game.id = UUID.randomUUID().toString()

@ -41,7 +41,7 @@ class GraphActivity : PokerAnalyticsActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_editable_data) setContentView(R.layout.activity_graph)
initUI() initUI()
} }

@ -27,6 +27,7 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow
import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.extensions.shortDate import net.pokeranalytics.android.util.extensions.shortDate
import net.pokeranalytics.android.util.extensions.shortTime
import net.pokeranalytics.android.util.extensions.toMinutes import net.pokeranalytics.android.util.extensions.toMinutes
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
@ -69,7 +70,7 @@ open class FilterDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresenta
Timber.d("Row: $row") Timber.d("Row: $row")
when (row) { when (row) {
is FilterElementRow.DateFilterElementRow -> DateTimePickerManager.create(requireContext(), row, this, row.dateValue, onlyDate = true) is FilterElementRow.DateFilterElementRow -> DateTimePickerManager.create(requireContext(), row, this, row.dateValue, onlyDate = !row.showTime, onlyTime = row.showTime)
is FilterElementRow.PastDays -> { is FilterElementRow.PastDays -> {
val pastDays = if (row.lastDays > 0) row.lastDays.toString() else "" val pastDays = if (row.lastDays > 0) row.lastDays.toString() else ""
val data = row.editingDescriptors(mapOf("pastDays" to pastDays)) val data = row.editingDescriptors(mapOf("pastDays" to pastDays))
@ -107,7 +108,7 @@ open class FilterDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresenta
is FilterElementRow.PastDays -> if (row.lastDays > 0) row.lastDays.toString() else NULL_TEXT is FilterElementRow.PastDays -> if (row.lastDays > 0) row.lastDays.toString() else NULL_TEXT
is FilterElementRow.LastGames -> if (row.lastGames > 0) row.lastGames.toString() else NULL_TEXT is FilterElementRow.LastGames -> if (row.lastGames > 0) row.lastGames.toString() else NULL_TEXT
is FilterElementRow.LastSessions -> if (row.lastSessions > 0) row.lastSessions.toString() else NULL_TEXT is FilterElementRow.LastSessions -> if (row.lastSessions > 0) row.lastSessions.toString() else NULL_TEXT
is FilterElementRow.DateFilterElementRow -> row.dateValue.shortDate() is FilterElementRow.DateFilterElementRow -> if (row.showTime) row.dateValue.shortTime() else row.dateValue.shortDate()
is FilterElementRow.AmountFilterElement -> if (row.amount > 0) row.amount.toString() else NULL_TEXT is FilterElementRow.AmountFilterElement -> if (row.amount > 0) row.amount.toString() else NULL_TEXT
is FilterElementRow.DurationFilterElement -> row.minutes.toMinutes(requireContext()) is FilterElementRow.DurationFilterElement -> row.minutes.toMinutes(requireContext())
else -> super.stringForRow(row) else -> super.stringForRow(row)
@ -243,7 +244,7 @@ open class FilterDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresenta
private fun saveData() { private fun saveData() {
//TODO: Save currentFilter details data //TODO: Save currentFilter details data
Timber.d("Save data for filter: ${currentFilter?.id}") Timber.d("Save data for filter: ${currentFilter?.id}")
selectedRows?.forEach { selectedRows.forEach {
Timber.d("Selected rows: $it") Timber.d("Selected rows: $it")
} }

@ -4,16 +4,24 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.github.mikephil.charting.charts.BarChart
import com.github.mikephil.charting.charts.BarLineChartBase
import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineData import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet import com.github.mikephil.charting.data.LineDataSet
import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.highlight.Highlight
import com.github.mikephil.charting.listener.OnChartValueSelectedListener import com.github.mikephil.charting.listener.OnChartValueSelectedListener
import kotlinx.android.synthetic.main.fragment_graph.* import com.google.android.material.chip.Chip
import kotlinx.android.synthetic.main.fragment_evograph.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.GraphType
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.fragment.components.PokerAnalyticsFragment import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.ui.graph.setStyle import net.pokeranalytics.android.ui.graph.setStyle
import net.pokeranalytics.android.ui.view.LegendView
import net.pokeranalytics.android.util.extensions.px
interface GraphDataSource { interface GraphDataSource {
@ -22,13 +30,16 @@ interface GraphDataSource {
class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener { class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener {
private lateinit var parentActivity: PokerAnalyticsActivity
lateinit var dataSource: GraphDataSource lateinit var dataSource: GraphDataSource
lateinit var stat: Stat lateinit var stat: Stat
lateinit var entries: List<Entry> lateinit var entries: List<Entry>
companion object { lateinit var legendView: LegendView
lateinit var chartView: BarLineChartBase<*>
companion object {
} }
@ -38,7 +49,7 @@ class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener {
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_graph, container, false) return inflater.inflate(R.layout.fragment_evograph, container, false)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -46,18 +57,63 @@ class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener {
initUI() initUI()
} }
/**
* Init UI
*/
private fun initUI() { private fun initUI() {
parentActivity = activity as PokerAnalyticsActivity
this.legendView = LegendView(requireContext())
this.legendContainer.addView(this.legendView)
this.legendView.prepareWithStat(this.stat)
// 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)
dataSet.setDrawCircles(false)
val lineData = LineData(listOf(dataSet)) val lineData = LineData(listOf(dataSet))
this.chart.setStyle() this.chartView = when (stat.graphType) {
GraphType.LINE -> {
val lineChart = LineChart(context)
lineChart.data = lineData
lineChart
}
GraphType.BAR -> {
val barChart = BarChart(context)
barChart
}
}
this.chartContainer.addView(this.chartView)
this.chartView.setStyle(requireContext())
this.chartView.setOnChartValueSelectedListener(this)
this.chart.data = lineData this.stat.aggregationTypes.forEach { type ->
this.chart.setOnChartValueSelectedListener(this) val chip = Chip(requireContext())
chip.id = type.ordinal
chip.text = requireContext().getString(type.resId)
chip.chipStartPadding = 8f.px
chip.chipEndPadding = 8f.px
this.chipGroup.addView(chip)
}
this.chipGroup.setOnCheckedChangeListener { group, i ->
}
this.chipGroup.check(this.stat.aggregationTypes.first().ordinal)
} }
// OnChartValueSelectedListener // OnChartValueSelectedListener
@ -85,7 +141,7 @@ class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener {
} }
this.text.text = "" // this.text.text = ""

@ -37,7 +37,7 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
private var stringTournament = "" private var stringTournament = ""
private lateinit var statsAdapter: RowRepresentableAdapter private lateinit var statsAdapter: RowRepresentableAdapter
private var computedResults : List<ComputedResults>? = null private var report : Report? = null
companion object { companion object {
@ -137,31 +137,31 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
GlobalScope.launch(coroutineContext) { GlobalScope.launch(coroutineContext) {
var results = listOf<ComputedResults>() var r = Report()
val test = GlobalScope.async { val test = GlobalScope.async {
val s = Date() val s = Date()
Timber.d(">>> start...") Timber.d(">>> start...")
val realm = Realm.getDefaultInstance() val realm = Realm.getDefaultInstance()
results = createSessionGroupsAndStartCompute(realm) r = createSessionGroupsAndStartCompute(realm)
computedResults = results report = r
realm.close() realm.close()
val e = Date() val e = Date()
val duration = (e.time - s.time) / 1000.0 val duration = (e.time - s.time) / 1000.0
Timber.d(">>> ended in ${duration} seconds") Timber.d(">>> ended in $duration seconds")
} }
test.await() test.await()
if (!isDetached) { if (!isDetached) {
showResults(results) showResults(r)
} }
} }
} }
private fun createSessionGroupsAndStartCompute(realm: Realm) : List<ComputedResults> { private fun createSessionGroupsAndStartCompute(realm: Realm) : Report {
val allStats: List<Stat> = listOf(Stat.NETRESULT, Stat.HOURLY_RATE, Stat.AVERAGE, Stat.NUMBER_OF_SETS, Stat.AVERAGE_DURATION, Stat.DURATION) val allStats: List<Stat> = listOf(Stat.NETRESULT, Stat.HOURLY_RATE, Stat.AVERAGE, Stat.NUMBER_OF_SETS, Stat.AVERAGE_DURATION, Stat.DURATION)
val allSessionGroup = ComputableGroup(stringAll, listOf(), allStats) val allSessionGroup = ComputableGroup(stringAll, listOf(), allStats)
@ -176,16 +176,16 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
} }
private fun showResults(results: List<ComputedResults>) { private fun showResults(report: Report) {
this.rowRepresentables = this.convertResultsIntoRepresentables(results) this.rowRepresentables = this.convertReportIntoRepresentables(report)
statsAdapter.notifyDataSetChanged() statsAdapter.notifyDataSetChanged()
} }
private fun convertResultsIntoRepresentables(results: List<ComputedResults>) : ArrayList<RowRepresentable> { private fun convertReportIntoRepresentables(report: Report) : ArrayList<RowRepresentable> {
val rows: ArrayList<RowRepresentable> = ArrayList() val rows: ArrayList<RowRepresentable> = ArrayList()
results.forEach { result -> report.results.forEach { result ->
rows.add(CustomizableRowRepresentable(title = result.group.name)) rows.add(CustomizableRowRepresentable(title = result.group.name))
result.group.stats?.forEach { stat -> result.group.stats?.forEach { stat ->
rows.add(StatRepresentable(stat, result.computedStat(stat), result.group.name)) rows.add(StatRepresentable(stat, result.computedStat(stat), result.group.name))
@ -202,7 +202,7 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
if (row is StatRepresentable) { if (row is StatRepresentable) {
// filter groups // filter groups
val groupResults = this.computedResults?.filter { val groupResults = this.report?.results?.filter {
it.group.name == row.groupName it.group.name == row.groupName
} }
@ -217,7 +217,7 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
GlobalScope.launch(coroutineContext) { GlobalScope.launch(coroutineContext) {
var results = listOf<ComputedResults>() var report = Report()
val test = GlobalScope.async { val test = GlobalScope.async {
val s = Date() val s = Date()
Timber.d(">>> start...") Timber.d(">>> start...")
@ -225,18 +225,18 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
val realm = Realm.getDefaultInstance() val realm = Realm.getDefaultInstance()
val options = Calculator.Options() val options = Calculator.Options()
options.evolutionValues = Calculator.Options.EvolutionValues.STANDARD options.evolutionValues = Calculator.Options.EvolutionValues.STANDARD
results = Calculator.computeGroups(realm, listOf(computableGroup), options) report = Calculator.computeGroups(realm, listOf(computableGroup), options)
realm.close() realm.close()
val e = Date() val e = Date()
val duration = (e.time - s.time) / 1000.0 val duration = (e.time - s.time) / 1000.0
Timber.d(">>> ended in ${duration} seconds") Timber.d(">>> ended in $duration seconds")
} }
test.await() test.await()
if (!isDetached) { if (!isDetached) {
results.firstOrNull()?.defaultStatEntries(stat)?.let { entries -> report.results.firstOrNull()?.defaultStatEntries(stat)?.let { entries ->
GraphActivity.newInstance(requireContext(), stat, entries) GraphActivity.newInstance(requireContext(), stat, entries)
} }
} }

@ -1,24 +1,34 @@
package net.pokeranalytics.android.ui.graph package net.pokeranalytics.android.ui.graph
import com.github.mikephil.charting.charts.BarChart import android.content.Context
import androidx.core.content.ContextCompat
import com.github.mikephil.charting.charts.BarLineChartBase import com.github.mikephil.charting.charts.BarLineChartBase
import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis
import net.pokeranalytics.android.R
import net.pokeranalytics.android.util.extensions.px
fun BarChart.setStyle() { //fun BarChart.setStyle(context: Context) {
GraphHelper.setStyle(this) // GraphHelper.setStyle(this, context)
} //}
fun LineChart.setStyle() { fun BarLineChartBase<*>.setStyle(context: Context) {
GraphHelper.setStyle(this) GraphHelper.setStyle(this, context)
} }
class GraphHelper { class GraphHelper {
companion object { companion object {
fun setStyle(chart: BarLineChartBase<*>) { fun setStyle(chart: BarLineChartBase<*>, context: Context) {
chart.xAxis.axisLineColor = ContextCompat.getColor(context, R.color.chart_default)
chart.xAxis.enableGridDashedLine(3.0f.px, 5.0f.px, 1.0f.px)
chart.xAxis.textColor = ContextCompat.getColor(context, R.color.chart_default)
chart.xAxis.labelCount = 4
chart.xAxis.position = XAxis.XAxisPosition.BOTTOM
chart.axisLeft.enableGridDashedLine(3.0f.px, 5.0f.px, 1.0f.px)
// this.xAxis.axisLineColor = ContextCompat.getColor(context, R.color.) ChartAppearance.defaultColor
// this.xAxis.axisLineWidth = ChartAppearance.lineWidth // this.xAxis.axisLineWidth = ChartAppearance.lineWidth
// this.xAxis.enableGridDashedLine(3.0f, 5.0f, 1.0f) // this.xAxis.enableGridDashedLine(3.0f, 5.0f, 1.0f)
// //

@ -23,6 +23,7 @@ class DateTimePickerManager : DatePickerDialog.OnDateSetListener,
private lateinit var calendar: Calendar private lateinit var calendar: Calendar
private var minimumDate: Date? = null private var minimumDate: Date? = null
private var onlyDate: Boolean = false private var onlyDate: Boolean = false
private var onlyTime: Boolean = false
private var isClearable: Boolean = true private var isClearable: Boolean = true
companion object { companion object {
@ -33,6 +34,7 @@ class DateTimePickerManager : DatePickerDialog.OnDateSetListener,
date: Date?, date: Date?,
minimumDate: Date? = null, minimumDate: Date? = null,
onlyDate: Boolean? = false, onlyDate: Boolean? = false,
onlyTime: Boolean? = false,
isClearable: Boolean? = true isClearable: Boolean? = true
): DateTimePickerManager { ): DateTimePickerManager {
@ -46,9 +48,14 @@ class DateTimePickerManager : DatePickerDialog.OnDateSetListener,
dateTimePickerManager.calendar = calendar dateTimePickerManager.calendar = calendar
dateTimePickerManager.minimumDate = minimumDate dateTimePickerManager.minimumDate = minimumDate
dateTimePickerManager.onlyDate = onlyDate ?: false dateTimePickerManager.onlyDate = onlyDate ?: false
dateTimePickerManager.onlyTime = onlyTime ?: false
dateTimePickerManager.isClearable = isClearable ?: true dateTimePickerManager.isClearable = isClearable ?: true
if (dateTimePickerManager.onlyTime) {
dateTimePickerManager.showTimePicker()
} else {
dateTimePickerManager.showDatePicker() dateTimePickerManager.showDatePicker()
}
return dateTimePickerManager return dateTimePickerManager
} }

@ -0,0 +1,69 @@
package net.pokeranalytics.android.ui.view
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import androidx.constraintlayout.widget.ConstraintLayout
import kotlinx.android.synthetic.main.layout_legend_default.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.model.realm.Session
/**
* Display a row session
*/
class LegendView : FrameLayout {
private lateinit var legendLayout: ConstraintLayout
/**
* Constructors
*/
constructor(context: Context) : super(context) {
init()
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
init()
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init()
}
/**
* Init
*/
private fun init() {
val layoutInflater = LayoutInflater.from(context)
legendLayout = layoutInflater.inflate(R.layout.layout_legend_default, this, false) as ConstraintLayout
val layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
addView(legendLayout, layoutParams)
}
/**
* Set the stat data to the view
*/
fun prepareWithStat(stat: Stat) {
this.stat1Name.text = stat.localizedTitle(context)
this.stat2Name.text = stat.cumulativeLabelResId(context)
//TODO: Set real data
this.title.text = "11/04/2019"
this.stat1Value.text = "$521"
this.stat2Value.text = "$15,051"
this.counter.text = "21 Sessions"
}
/**
*
*/
fun setData(session: Session) {
}
}

@ -11,6 +11,10 @@ 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.NULL_TEXT
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.*
import java.util.prefs.Preferences import java.util.prefs.Preferences
@ -26,7 +30,7 @@ sealed class FilterElementRow : RowRepresentable {
interface LessOperator : Operator interface LessOperator : Operator
open class BoolFilterElementRow : FilterElementRow() open class BoolFilterElementRow : FilterElementRow()
open class DateFilterElementRow(var dateValue: Date = Date()) : FilterElementRow() open class DateFilterElementRow(var dateValue: Date = Date(), var showTime: Boolean = false) : FilterElementRow()
open class NumericFilterElementRow(open val doubleValue: Double = 0.0) : FilterElementRow() open class NumericFilterElementRow(open val doubleValue: Double = 0.0) : FilterElementRow()
open class StringFilterElementRow(val stringValue: String = "") : FilterElementRow() open class StringFilterElementRow(val stringValue: String = "") : FilterElementRow()
@ -84,6 +88,10 @@ sealed class FilterElementRow : RowRepresentable {
object From : DateFilterElementRow() object From : DateFilterElementRow()
object To : DateFilterElementRow() object To : DateFilterElementRow()
object FromTime : DateFilterElementRow(showTime = true)
object ToTime : DateFilterElementRow(showTime = true)
// Data classes - holding value // Data classes - holding value
object ResultMoreThan : AmountFilterElement(), MoreOperator object ResultMoreThan : AmountFilterElement(), MoreOperator
@ -144,6 +152,8 @@ sealed class FilterElementRow : RowRepresentable {
is Stake -> QueryCondition.STAKE is Stake -> QueryCondition.STAKE
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 ToTime -> QueryCondition.ENDED_TO_TIME
is Month -> QueryCondition.MONTH is Month -> QueryCondition.MONTH
is Day -> QueryCondition.DAY_OF_WEEK is Day -> QueryCondition.DAY_OF_WEEK
is Year -> QueryCondition.YEAR is Year -> QueryCondition.YEAR
@ -171,7 +181,6 @@ sealed class FilterElementRow : RowRepresentable {
is DurationMoreThan -> QueryCondition.MORE_THAN_DURATION is DurationMoreThan -> QueryCondition.MORE_THAN_DURATION
is DurationLessThan -> QueryCondition.LESS_THAN_DURATION is DurationLessThan -> QueryCondition.LESS_THAN_DURATION
//TODO: Check the conditions //TODO: Check the conditions
is LastGames -> QueryCondition.LAST_GAMES is LastGames -> QueryCondition.LAST_GAMES
is LastSessions -> QueryCondition.LAST_SESSIONS is LastSessions -> QueryCondition.LAST_SESSIONS
@ -206,8 +215,8 @@ sealed class FilterElementRow : RowRepresentable {
is CurrentWeek -> R.string.current_week is CurrentWeek -> R.string.current_week
is CurrentMonth -> R.string.current_month is CurrentMonth -> R.string.current_month
is CurrentYear -> R.string.current_year is CurrentYear -> R.string.current_year
is From -> R.string.from is From, FromTime -> R.string.from
is To -> R.string.to is To, ToTime -> R.string.to
is Live -> R.string.live is Live -> R.string.live
is Online -> R.string.online is Online -> R.string.online
is Weekday -> R.string.week_days is Weekday -> R.string.week_days
@ -226,7 +235,7 @@ sealed class FilterElementRow : RowRepresentable {
override val viewType: Int override val viewType: Int
get() { get() {
return when (this) { return when (this) {
is PastDays, is From, is To, is LastGames, is LastSessions, is ReBuyMoreThan, is ReBuyLessThan, is PastDays, is From, is To, is FromTime, is ToTime, is LastGames, is LastSessions, is ReBuyMoreThan, is ReBuyLessThan,
is DurationMoreThan, is DurationLessThan -> RowViewType.TITLE_VALUE_CHECK.ordinal is DurationMoreThan, is DurationLessThan -> RowViewType.TITLE_VALUE_CHECK.ordinal
else -> RowViewType.TITLE_CHECK.ordinal else -> RowViewType.TITLE_CHECK.ordinal
} }
@ -333,22 +342,4 @@ sealed class FilterElementRow : RowRepresentable {
return null return null
} }
/*
override fun editingDescriptors(map: Map<String, Any?>): ArrayList<RowRepresentableEditDescriptor>? {
when (this) {
PAST_DAYS -> {
val defaultValue: String? by map
val data = arrayListOf<RowRepresentableEditDescriptor>()
data.add(
RowRepresentableEditDescriptor(
defaultValue,
inputType = InputType.TYPE_CLASS_NUMBER
)
)
}
}
return super.editingDescriptors(map)
}
*/
} }

@ -9,6 +9,8 @@ import net.pokeranalytics.android.model.realm.Session
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.ui.view.rowrepresentable.FilterElementRow.* import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow.*
import net.pokeranalytics.android.util.extensions.endOfDay
import net.pokeranalytics.android.util.extensions.startOfDay
import java.text.DateFormatSymbols import java.text.DateFormatSymbols
import java.util.* import java.util.*
@ -86,7 +88,8 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable {
TABLE_SIZE -> { TABLE_SIZE -> {
val tableSizes = arrayListOf<FilterElementRow.TableSize>() val tableSizes = arrayListOf<FilterElementRow.TableSize>()
val realm = Realm.getDefaultInstance() val realm = Realm.getDefaultInstance()
val distinctTableSizes = realm.where<Session>().distinct("tableSize").findAll().sort("tableSize", Sort.ASCENDING) val distinctTableSizes =
realm.where<Session>().distinct("tableSize").findAll().sort("tableSize", Sort.ASCENDING)
distinctTableSizes.forEach { session -> distinctTableSizes.forEach { session ->
session.tableSize?.let { tableSize -> session.tableSize?.let { tableSize ->
tableSizes.add(TableSize(net.pokeranalytics.android.model.TableSize(tableSize))) tableSizes.add(TableSize(net.pokeranalytics.android.model.TableSize(tableSize)))
@ -110,7 +113,8 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable {
YEAR -> { YEAR -> {
val years = arrayListOf<FilterElementRow.Year>() val years = arrayListOf<FilterElementRow.Year>()
val realm = Realm.getDefaultInstance() val realm = Realm.getDefaultInstance()
val distinctYears = realm.where<Session>().distinct("year").findAll().sort("year", Sort.DESCENDING) val distinctYears =
realm.where<Session>().distinct("year").findAll().sort("year", Sort.DESCENDING)
distinctYears.forEach { session -> distinctYears.forEach { session ->
session.year?.let { year -> session.year?.let { year ->
years.add(Year(year)) years.add(Year(year))
@ -140,8 +144,17 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable {
} }
// Duration // Duration
SESSION_DURATION -> arrayListOf(DurationMoreThan as FilterElementRow, DurationLessThan as FilterElementRow) SESSION_DURATION -> arrayListOf(
RANGE -> arrayListOf(From, To) DurationMoreThan as FilterElementRow,
DurationLessThan as FilterElementRow
)
RANGE -> {
val fromTime = FromTime
fromTime.dateValue = Date().startOfDay()
val toTime = ToTime
toTime.dateValue = Date().endOfDay()
arrayListOf(fromTime, toTime)
}
// Sessions // Sessions
SESSIONS -> arrayListOf(LastGames(0), LastSessions(0)) SESSIONS -> arrayListOf(LastGames(0), LastSessions(0))
@ -158,7 +171,10 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable {
realm.close() realm.close()
stakes stakes
} }
CASH_RE_BUY_COUNT -> arrayListOf(ReBuyMoreThan as FilterElementRow, ReBuyLessThan as FilterElementRow) CASH_RE_BUY_COUNT -> arrayListOf(
ReBuyMoreThan as FilterElementRow,
ReBuyLessThan as FilterElementRow
)
// Tournament // Tournament
TOURNAMENT_TYPE -> arrayListOf() TOURNAMENT_TYPE -> arrayListOf()

@ -13,7 +13,7 @@ class CurrencyUtils {
* return the currency associated with this bankroll * return the currency associated with this bankroll
*/ */
fun getCurrency(bankroll: Bankroll? = null) : Currency { fun getCurrency(bankroll: Bankroll? = null) : Currency {
val currencyCode = bankroll?.currency?.code ?: Currency.getInstance(Locale.getDefault()).currencyCode val currencyCode = bankroll?.currency?.code ?: CurrencyUtils.getLocaleCurrency().currencyCode
return Currency.getInstance(currencyCode) return Currency.getInstance(currencyCode)
} }
@ -40,6 +40,25 @@ class CurrencyUtils {
return currencyFormatter 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"))
}
}
}
} }
} }

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container" android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">

@ -0,0 +1,59 @@
<?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">
<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/legendContainer"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar" />
<FrameLayout
android:id="@+id/chartContainer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@id/chips"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/legendContainer" />
<FrameLayout
android:id="@+id/chips"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:layout_height="60dp">
<com.google.android.material.chip.ChipGroup
android:id="@+id/chipGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal"
app:chipSpacingHorizontal="8dp"
app:singleSelection="true"
tools:layout_height="60dp" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -1,25 +0,0 @@
<?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">
<TextView
android:id="@+id/text"
android:textColor="@color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp"
app:layout_constraintTop_toTopOf="@+id/chart"
android:layout_marginTop="8dp"/>
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,94 @@
<?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="wrap_content"
android:orientation="vertical">
<View
android:id="@+id/background"
android:background="@color/green_header"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/counter"
android:layout_marginBottom="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/title"
style="@style/PokerAnalyticsTheme.TextView.LegendTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="11/04/2019" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/stat1Name"
style="@style/PokerAnalyticsTheme.TextView.LegendStatsTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title"
tools:text="NET RESULT" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/stat1Value"
style="@style/PokerAnalyticsTheme.TextView.LegendStatsValue"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
app:layout_constraintEnd_toStartOf="@+id/stat2Value"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/stat1Name"
tools:text="$2000" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/stat2Name"
style="@style/PokerAnalyticsTheme.TextView.LegendStatsTitle"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@+id/stat1Name"
app:layout_constraintTop_toBottomOf="@id/title"
tools:text="NET RESULT" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/stat2Value"
style="@style/PokerAnalyticsTheme.TextView.LegendStatsValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@+id/stat1Value"
app:layout_constraintTop_toBottomOf="@id/stat2Name"
tools:text="$2000000000" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/counter"
style="@style/PokerAnalyticsTheme.TextView.LegendSubtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/stat2Value"
tools:text="152 sessions" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -37,4 +37,6 @@
<color name="purple">#8e35c8</color> <color name="purple">#8e35c8</color>
<color name="chart_default">#5c7258</color>
</resources> </resources>

@ -1,7 +1,7 @@
<resources> <resources>
<!-- PokerAnalytics application theme --> <!-- PokerAnalytics application theme -->
<style name="PokerAnalyticsTheme" parent="Theme.MaterialComponents.Light.NoActionBar"> <style name="PokerAnalyticsTheme" parent="Theme.MaterialComponents.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
@ -10,6 +10,7 @@
<item name="android:windowBackground">@color/gray_dark</item> <item name="android:windowBackground">@color/gray_dark</item>
<item name="android:navigationBarColor">@color/colorPrimary</item> <item name="android:navigationBarColor">@color/colorPrimary</item>
<item name="android:actionMenuTextColor">@color/white</item> <item name="android:actionMenuTextColor">@color/white</item>
<item name="colorControlNormal">@color/white</item>
<item name="bottomNavigationStyle">@style/PokerAnalyticsTheme.BottomNavigationView</item> <item name="bottomNavigationStyle">@style/PokerAnalyticsTheme.BottomNavigationView</item>
<item name="toolbarStyle">@style/PokerAnalyticsTheme.Toolbar</item> <item name="toolbarStyle">@style/PokerAnalyticsTheme.Toolbar</item>
@ -23,14 +24,18 @@
<!-- Defaults --> <!-- Defaults -->
<!-- Bottom Bar --> <!-- Bottom Bar -->
<style name="PokerAnalyticsTheme.BottomNavigationView"> <style name="PokerAnalyticsTheme.BottomNavigationView">
<item name="itemIconTint">@color/bottom_navigation_item</item> <item name="itemIconTint">@color/bottom_navigation_item</item>
<item name="itemTextColor">@color/bottom_navigation_item</item> <item name="itemTextColor">@color/bottom_navigation_item</item>
<item name="android:background">@color/gray_darker</item> <item name="android:background">@color/gray_darker</item>
</style> </style>
<!-- Toolbar --> <!-- Toolbar -->
<style name="PokerAnalyticsTheme.Toolbar" parent="Widget.MaterialComponents.Toolbar"> <style name="PokerAnalyticsTheme.Toolbar" parent="Widget.MaterialComponents.Toolbar">
<item name="android:background">@color/gray_darker</item> <item name="android:background">@color/gray_darker</item>
<item name="titleTextColor">@color/white</item> <item name="titleTextColor">@color/white</item>
@ -40,6 +45,7 @@
<style name="PokerAnalyticsTheme.Toolbar.TitleAppearance"> <style name="PokerAnalyticsTheme.Toolbar.TitleAppearance">
<item name="android:textSize">20sp</item> <item name="android:textSize">20sp</item>
<item name="android:fontFamily">@font/roboto</item> <item name="android:fontFamily">@font/roboto</item>
<item name="titleTextColor">@color/white</item>
</style> </style>
<style name="PokerAnalyticsTheme.Toolbar.ExpandedTitleAppearance"> <style name="PokerAnalyticsTheme.Toolbar.ExpandedTitleAppearance">
@ -54,9 +60,11 @@
<style name="PokerAnalyticsTheme.Toolbar.Session" parent="ThemeOverlay.AppCompat.Dark.ActionBar"> <style name="PokerAnalyticsTheme.Toolbar.Session" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
<item name="android:actionMenuTextColor">@color/green</item> <item name="android:actionMenuTextColor">@color/green</item>
<item name="titleTextAppearance">@style/PokerAnalyticsTheme.Toolbar.TitleAppearance</item>
</style> </style>
<!-- Bottom App Bar --> <!-- Bottom App Bar -->
<style name="PokerAnalyticsTheme.BottomAppBar" parent="Widget.MaterialComponents.BottomAppBar"> <style name="PokerAnalyticsTheme.BottomAppBar" parent="Widget.MaterialComponents.BottomAppBar">
<item name="backgroundTint">@color/gray_darker</item> <item name="backgroundTint">@color/gray_darker</item>
<item name="android:colorPrimary">@color/white</item> <item name="android:colorPrimary">@color/white</item>
@ -64,7 +72,9 @@
<item name="popupTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item> <item name="popupTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
</style> </style>
<!-- TextView --> <!-- TextView -->
<style name="PokerAnalyticsTheme.TextView"> <style name="PokerAnalyticsTheme.TextView">
<item name="android:textColor">@color/white</item> <item name="android:textColor">@color/white</item>
<item name="android:fontFamily">@font/roboto</item> <item name="android:fontFamily">@font/roboto</item>
@ -124,13 +134,52 @@
<item name="android:ellipsize">end</item> <item name="android:ellipsize">end</item>
</style> </style>
<!-- Graph legend -->
<style name="PokerAnalyticsTheme.TextView.LegendTitle">
<item name="android:textSize">24sp</item>
<item name="android:textColor">@color/white</item>
<item name="android:fontFamily">@font/roboto</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
</style>
<style name="PokerAnalyticsTheme.TextView.LegendSubtitle">
<item name="android:textSize">12sp</item>
<item name="android:textColor">@color/kaki_light</item>
<item name="android:fontFamily">@font/roboto</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
</style>
<style name="PokerAnalyticsTheme.TextView.LegendStatsTitle">
<item name="android:textSize">14sp</item>
<item name="android:textColor">@color/white</item>
<item name="android:fontFamily">@font/roboto_bold</item>
<item name="android:textAllCaps">true</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
</style>
<style name="PokerAnalyticsTheme.TextView.LegendStatsValue">
<item name="android:textSize">24sp</item>
<item name="android:textColor">@color/white</item>
<item name="android:fontFamily">@font/roboto_light</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
</style>
<!-- Bottom Sheet --> <!-- Bottom Sheet -->
<style name="PokerAnalyticsTheme.TextView.BottomSheetValue"> <style name="PokerAnalyticsTheme.TextView.BottomSheetValue">
<item name="android:textSize">22sp</item> <item name="android:textSize">22sp</item>
<item name="android:textColor">@color/white</item> <item name="android:textColor">@color/white</item>
<item name="android:fontFamily">@font/roboto</item> <item name="android:fontFamily">@font/roboto</item>
</style> </style>
<!-- Session Row --> <!-- Session Row -->
<style name="PokerAnalyticsTheme.TextView.SessionRow"> <style name="PokerAnalyticsTheme.TextView.SessionRow">
@ -168,7 +217,9 @@
<item name="android:textColor">@color/green</item> <item name="android:textColor">@color/green</item>
</style> </style>
<!-- Button Row --> <!-- Button Row -->
<style name="PokerAnalyticsTheme.TextView.ButtonRow"> <style name="PokerAnalyticsTheme.TextView.ButtonRow">
<item name="android:textColor">@color/colorAccent</item> <item name="android:textColor">@color/colorAccent</item>
<item name="android:maxLines">1</item> <item name="android:maxLines">1</item>
@ -180,6 +231,7 @@
<!-- Alert Dialog --> <!-- Alert Dialog -->
<style name="PokerAnalyticsTheme.AlertDialog" parent="Theme.MaterialComponents.Dialog"> <style name="PokerAnalyticsTheme.AlertDialog" parent="Theme.MaterialComponents.Dialog">
<item name="colorAccent">@color/green</item> <item name="colorAccent">@color/green</item>
<item name="android:textColorPrimary">@color/white</item> <item name="android:textColorPrimary">@color/white</item>
@ -188,6 +240,7 @@
<!-- EditText --> <!-- EditText -->
<style name="PokerAnalyticsTheme.EditText" parent="Widget.AppCompat.EditText"> <style name="PokerAnalyticsTheme.EditText" parent="Widget.AppCompat.EditText">
<item name="android:textColor">@color/white</item> <item name="android:textColor">@color/white</item>
<item name="android:fontFamily">@font/roboto</item> <item name="android:fontFamily">@font/roboto</item>
@ -196,7 +249,9 @@
<item name="android:paddingBottom">16dp</item> <item name="android:paddingBottom">16dp</item>
</style> </style>
<!-- Button --> <!-- Button -->
<style name="PokerAnalyticsTheme.Button" parent="Widget.MaterialComponents.Button"> <style name="PokerAnalyticsTheme.Button" parent="Widget.MaterialComponents.Button">
<item name="iconPadding">0dp</item> <item name="iconPadding">0dp</item>
<item name="android:height">48dp</item> <item name="android:height">48dp</item>
@ -215,7 +270,9 @@
<item name="android:fontFamily">@font/roboto_bold</item> <item name="android:fontFamily">@font/roboto_bold</item>
</style> </style>
<!-- Chip --> <!-- Chip -->
<style name="PokerAnalyticsTheme.Chip" parent="Widget.MaterialComponents.Chip.Choice"> <style name="PokerAnalyticsTheme.Chip" parent="Widget.MaterialComponents.Chip.Choice">
<item name="chipBackgroundColor">@color/chips_background_states</item> <item name="chipBackgroundColor">@color/chips_background_states</item>
<item name="android:textColor">@color/white</item> <item name="android:textColor">@color/white</item>

Loading…
Cancel
Save