Refactoring of getDisplayName to have a Context passed + Custom Report display

dev
Laurent 7 years ago
parent 2202e56524
commit 2b4fcb0a3d
  1. 17
      app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt
  2. 22
      app/src/main/java/net/pokeranalytics/android/calculus/Report.kt
  3. 3
      app/src/main/java/net/pokeranalytics/android/model/Limit.kt
  4. 2
      app/src/main/java/net/pokeranalytics/android/model/TableSize.kt
  5. 3
      app/src/main/java/net/pokeranalytics/android/model/TournamentType.kt
  6. 15
      app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt
  7. 49
      app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt
  8. 3
      app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt
  9. 3
      app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt
  10. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt
  11. 6
      app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt
  12. 3
      app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt
  13. 3
      app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt
  14. 3
      app/src/main/java/net/pokeranalytics/android/model/realm/ReportSetup.kt
  15. 16
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  16. 4
      app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt
  17. 3
      app/src/main/java/net/pokeranalytics/android/model/realm/TournamentFeature.kt
  18. 3
      app/src/main/java/net/pokeranalytics/android/model/realm/TournamentName.kt
  19. 4
      app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt
  20. 3
      app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt
  21. 5
      app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt
  22. 2
      app/src/main/java/net/pokeranalytics/android/ui/activity/ProgressReportActivity.kt
  23. 4
      app/src/main/java/net/pokeranalytics/android/ui/activity/TableReportActivity.kt
  24. 4
      app/src/main/java/net/pokeranalytics/android/ui/adapter/ReportPagerAdapter.kt
  25. 3
      app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt
  26. 1
      app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt
  27. 1
      app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarFragment.kt
  28. 3
      app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt
  29. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/MoreFragment.kt
  30. 3
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt
  31. 66
      app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt
  32. 11
      app/src/main/java/net/pokeranalytics/android/ui/fragment/report/AbstractReportFragment.kt
  33. 29
      app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComparisonReportFragment.kt
  34. 221
      app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComposableTableReportFragment.kt
  35. 9
      app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ProgressReportFragment.kt
  36. 186
      app/src/main/java/net/pokeranalytics/android/ui/fragment/report/TableReportFragment.kt
  37. 6
      app/src/main/java/net/pokeranalytics/android/ui/graph/GraphUnderlyingEntry.kt
  38. 2
      app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt
  39. 2
      app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt
  40. 0
      app/src/main/res/layout/activity_progress_report.xml
  41. 17
      app/src/main/res/layout/fragment_composable_table_report.xml
  42. 14
      app/src/main/res/layout/fragment_stats.xml
  43. 27
      app/src/main/res/layout/fragment_table_report.xml

@ -1,5 +1,6 @@
package net.pokeranalytics.android.calculus package net.pokeranalytics.android.calculus
import android.content.Context
import io.realm.Realm import io.realm.Realm
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Stat.* import net.pokeranalytics.android.calculus.Stat.*
@ -14,7 +15,6 @@ import net.pokeranalytics.android.model.realm.ReportSetup
import net.pokeranalytics.android.model.realm.SessionSet import net.pokeranalytics.android.model.realm.SessionSet
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.util.extensions.startOfDay import net.pokeranalytics.android.util.extensions.startOfDay
import timber.log.Timber
import java.util.* import java.util.*
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@ -151,14 +151,13 @@ class Calculator {
} }
/** /**
* Returns some default generated name * Returns some default name
*/ */
val defaultName: String fun getName(context: Context): String {
get() { return when (this.stats.size) {
val statName = this.stats.firstOrNull()?.let { 1 -> this.stats.first().localizedTitle(context)
it.getDisplayName() else -> this.query.getName(context)
} }
return statName ?: this.query.name
} }
} }
@ -244,7 +243,7 @@ class Calculator {
val e = Date() val e = Date()
val duration = (e.time - s.time) / 1000.0 val duration = (e.time - s.time) / 1000.0
Timber.d(">>> group ${group.name} in $duration seconds") // Timber.d(">>> group ${group.name} in $duration seconds")
} }
@ -259,7 +258,7 @@ class Calculator {
val results = ComputedResults(computableGroup, options.shouldManageMultiGroupProgressValues) val results = ComputedResults(computableGroup, options.shouldManageMultiGroupProgressValues)
val computables = computableGroup.computables(realm, options.shouldSortValues) val computables = computableGroup.computables(realm, options.shouldSortValues)
Timber.d(">>>> Start computing group ${computableGroup.name}, ${computables.size} computables") // Timber.d(">>>> Start computing group ${computableGroup.name}, ${computables.size} computables")
results.addStat(NUMBER_OF_GAMES, computables.size.toDouble()) results.addStat(NUMBER_OF_GAMES, computables.size.toDouble())
val sum = computables.sum(ComputableResult.Field.RATED_NET.identifier).toDouble() val sum = computables.sum(ComputableResult.Field.RATED_NET.identifier).toDouble()

@ -106,10 +106,10 @@ class ComputableGroup(query: Query, stats: List<Stat>? = null) {
/** /**
* The display name of the group * The display name of the group
*/ */
val name: String // val name: String
get() { // get() {
return this.query.name // return this.query.name
} // }
/** /**
* A list of _conditions to get * A list of _conditions to get
@ -386,7 +386,7 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu
entries.add(Entry(index.toFloat(), p.y.toFloat(), p.data)) entries.add(Entry(index.toFloat(), p.y.toFloat(), p.data))
} }
} }
return DataSetFactory.lineDataSetInstance(entries, this.group.name, context) return DataSetFactory.lineDataSetInstance(entries, this.group.query.getName(context), context)
} }
fun durationEntries(stat: Stat, context: Context): LineDataSet { fun durationEntries(stat: Stat, context: Context): LineDataSet {
@ -449,7 +449,9 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu
// Stat Entry // Stat Entry
override val entryTitle: String = this.group.name override fun entryTitle(context: Context): String {
return this.group.query.getName(context)
}
override fun formattedValue(stat: Stat): TextFormat { override fun formattedValue(stat: Stat): TextFormat {
this.computedStat(stat)?.let { this.computedStat(stat)?.let {
@ -473,12 +475,12 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu
return when (stat) { return when (stat) {
Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_GAMES, Stat.WIN_RATIO -> { Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_GAMES, Stat.WIN_RATIO -> {
val totalStatValue = stat.format(entry.y.toDouble(), currency = null) val totalStatValue = stat.format(entry.y.toDouble(), currency = null)
DefaultLegendValues(this.entryTitle, totalStatValue) DefaultLegendValues(this.entryTitle(context), totalStatValue)
} }
else -> { else -> {
val entryValue = this.formattedValue(stat) val entryValue = this.formattedValue(stat)
val countValue = this.computedStat(Stat.NUMBER_OF_GAMES)?.format() val countValue = this.computedStat(Stat.NUMBER_OF_GAMES)?.format()
DefaultLegendValues(this.entryTitle, entryValue, countValue) DefaultLegendValues(this.entryTitle(context), entryValue, countValue)
} }
} }
} }
@ -487,12 +489,12 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu
return when (stat) { return when (stat) {
Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_GAMES, Stat.WIN_RATIO -> { Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_GAMES, Stat.WIN_RATIO -> {
val totalStatValue = stat.format(entry.y.toDouble(), currency = null) val totalStatValue = stat.format(entry.y.toDouble(), currency = null)
DefaultLegendValues(this.entryTitle, totalStatValue) DefaultLegendValues(this.entryTitle(context), totalStatValue)
} }
else -> { else -> {
val entryValue = this.formattedValue(stat) val entryValue = this.formattedValue(stat)
val totalStatValue = stat.format(entry.y.toDouble(), currency = null) val totalStatValue = stat.format(entry.y.toDouble(), currency = null)
DefaultLegendValues(this.entryTitle, entryValue, totalStatValue) DefaultLegendValues(this.entryTitle(context), entryValue, totalStatValue)
} }
} }

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model package net.pokeranalytics.android.model
import android.content.Context
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
enum class Limit : RowRepresentable { enum class Limit : RowRepresentable {
@ -32,7 +33,7 @@ enum class Limit : RowRepresentable {
} }
} }
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return this.longName return this.longName
} }
} }

@ -14,7 +14,7 @@ class TableSize(var numberOfPlayer: Int, var rowViewType: Int = RowViewType.TITL
} }
} }
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return if (this.numberOfPlayer == 2) { return if (this.numberOfPlayer == 2) {
return "HU" return "HU"
} else { } else {

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model package net.pokeranalytics.android.model
import android.content.Context
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
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
@ -23,7 +24,7 @@ enum class TournamentType : RowRepresentable {
} }
} }
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return when (this) { return when (this) {
MTT -> "MTT" MTT -> "MTT"
SNG -> "SNG" SNG -> "SNG"

@ -1,6 +1,8 @@
package net.pokeranalytics.android.model.filter package net.pokeranalytics.android.model.filter
import android.content.Context
import io.realm.RealmQuery import io.realm.RealmQuery
import net.pokeranalytics.android.R
fun List<Query>.mapFirstCondition() : List<QueryCondition> { fun List<Query>.mapFirstCondition() : List<QueryCondition> {
return this.map { it.conditions.first() } return this.map { it.conditions.first() }
@ -38,11 +40,18 @@ class Query {
this._conditions.addAll(queryConditions) this._conditions.addAll(queryConditions)
} }
val name: String fun getName(context: Context): String {
get() { return when (this._conditions.size) {
return this._conditions.joinToString(" : ") { it.getDisplayName() } 0 -> context.getString(R.string.all_sessions) // @todo should be dependant of the underlying type, ie. Session, Transaction...
else -> this._conditions.joinToString(" : ") { it.getDisplayName(context) }
}
} }
// val name: String
// get() {
// return this._conditions.joinToString(" : ") { it.getDisplayName() }
// }
inline fun <reified T : Filterable> queryWith(query: RealmQuery<T>): RealmQuery<T> { inline fun <reified T : Filterable> queryWith(query: RealmQuery<T>): RealmQuery<T> {
var realmQuery = query var realmQuery = query
this.conditions.forEach { this.conditions.forEach {

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.filter package net.pokeranalytics.android.model.filter
import android.content.Context
import io.realm.Realm import io.realm.Realm
import io.realm.RealmQuery import io.realm.RealmQuery
import io.realm.RealmResults import io.realm.RealmResults
@ -106,12 +107,12 @@ sealed class QueryCondition : FilterElementRow {
abstract class ListOfValues<T>: QueryCondition(), Comparable<ListOfValues<T>> where T:Comparable<T> { abstract class ListOfValues<T>: QueryCondition(), Comparable<ListOfValues<T>> where T:Comparable<T> {
abstract var listOfValues: ArrayList<T> abstract var listOfValues: ArrayList<T>
abstract fun labelForValue(value:T): String abstract fun labelForValue(value:T, context: Context): String
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return when (listOfValues.size) { return when (listOfValues.size) {
0 -> return NULL_TEXT 0 -> return NULL_TEXT
1,2 -> listOfValues.map { labelForValue(it) }.joinToString(", ") 1,2 -> listOfValues.map { labelForValue(it, context) }.joinToString(", ")
else -> "${listOfValues.size} $baseId" else -> "${listOfValues.size} $baseId"
} }
} }
@ -134,7 +135,7 @@ sealed class QueryCondition : FilterElementRow {
super.updateValueBy(filterCondition) super.updateValueBy(filterCondition)
listOfValues = filterCondition.getValues() listOfValues = filterCondition.getValues()
} }
override fun labelForValue(value: Double): String { override fun labelForValue(value: Double, context: Context): String {
return value.toCurrency(UserDefaults.currency) return value.toCurrency(UserDefaults.currency)
} }
} }
@ -145,14 +146,14 @@ sealed class QueryCondition : FilterElementRow {
super.updateValueBy(filterCondition) super.updateValueBy(filterCondition)
listOfValues = filterCondition.getValues() listOfValues = filterCondition.getValues()
} }
override fun labelForValue(value: Int): String { override fun labelForValue(value: Int, context: Context): String {
return value.toString() return value.toString()
} }
} }
abstract class ListOfString: ListOfValues<String>() { abstract class ListOfString: ListOfValues<String>() {
override var listOfValues = ArrayList<String>() override var listOfValues = ArrayList<String>()
override fun labelForValue(value: String): String { return value } override fun labelForValue(value: String, context: Context): String { return value }
override fun updateValueBy(filterCondition: FilterCondition) { override fun updateValueBy(filterCondition: FilterCondition) {
super.updateValueBy(filterCondition) super.updateValueBy(filterCondition)
listOfValues = filterCondition.getValues() listOfValues = filterCondition.getValues()
@ -160,7 +161,7 @@ sealed class QueryCondition : FilterElementRow {
} }
abstract class SingleDate: SingleValue<Date>() { abstract class SingleDate: SingleValue<Date>() {
override fun labelForValue(value: Date): String { override fun labelForValue(value: Date, context: Context): String {
return value.toString() return value.toString()
} }
@ -175,7 +176,7 @@ sealed class QueryCondition : FilterElementRow {
} }
abstract class SingleInt: SingleValue<Int>() { abstract class SingleInt: SingleValue<Int>() {
override fun labelForValue(value: Int): String { override fun labelForValue(value: Int, context: Context): String {
return value.toString() return value.toString()
} }
override var singleValue: Int override var singleValue: Int
@ -188,7 +189,7 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
override fun getDisplayName(): String { return baseId } override fun getDisplayName(context: Context): String { return baseId }
override var filterSectionRow: FilterSectionRow = FilterSectionRow.CASH_TOURNAMENT override var filterSectionRow: FilterSectionRow = FilterSectionRow.CASH_TOURNAMENT
@ -200,7 +201,7 @@ sealed class QueryCondition : FilterElementRow {
abstract val entity : Class<T> abstract val entity : Class<T>
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
val realm = Realm.getDefaultInstance() val realm = Realm.getDefaultInstance()
val completeLabel = when (listOfValues.size) { val completeLabel = when (listOfValues.size) {
0 -> return NULL_TEXT 0 -> return NULL_TEXT
@ -234,19 +235,19 @@ sealed class QueryCondition : FilterElementRow {
} }
object IsLive : QueryCondition() { object IsLive : QueryCondition() {
override fun getDisplayName(): String { return "Live" } override fun getDisplayName(context: Context): String { return "Live" }
} }
object IsCash : QueryCondition() { object IsCash : QueryCondition() {
override fun getDisplayName(): String { return "Cash" } override fun getDisplayName(context: Context): String { return "Cash" }
} }
object IsOnline : QueryCondition() { object IsOnline : QueryCondition() {
override fun getDisplayName(): String { return "Online" } override fun getDisplayName(context: Context): String { return "Online" }
} }
object IsTournament : QueryCondition() { object IsTournament : QueryCondition() {
override fun getDisplayName(): String { return "Tournament" } override fun getDisplayName(context: Context): String { return "Tournament" }
} }
class AnyBankroll(): QueryDataCondition<Bankroll>() { class AnyBankroll(): QueryDataCondition<Bankroll>() {
@ -300,20 +301,20 @@ sealed class QueryCondition : FilterElementRow {
} }
class AnyLimit: ListOfInt() { class AnyLimit: ListOfInt() {
override fun labelForValue(value: Int): String { override fun labelForValue(value: Int, context: Context): String {
return Limit.values()[value].getDisplayName() return Limit.values()[value].getDisplayName(context)
} }
} }
class AnyTableSize: ListOfInt() { class AnyTableSize: ListOfInt() {
override fun labelForValue(value: Int): String { override fun labelForValue(value: Int, context: Context): String {
return TableSize(value).getDisplayName() return TableSize(value).getDisplayName(context)
} }
} }
class AnyTournamentType: ListOfInt() { class AnyTournamentType: ListOfInt() {
override fun labelForValue(value: Int): String { override fun labelForValue(value: Int, context: Context): String {
return TournamentType.values()[value].getDisplayName() return TournamentType.values()[value].getDisplayName(context)
} }
} }
@ -350,13 +351,13 @@ sealed class QueryCondition : FilterElementRow {
class EndedToDate: DateQuery() { override var operator = Operator.LESS } class EndedToDate: DateQuery() { override var operator = Operator.LESS }
class AnyDayOfWeek: ListOfInt() { class AnyDayOfWeek: ListOfInt() {
override fun labelForValue(value: Int): String { override fun labelForValue(value: Int, context: Context): String {
return DateFormatSymbols.getInstance(Locale.getDefault()).weekdays[value] return DateFormatSymbols.getInstance(Locale.getDefault()).weekdays[value]
} }
} }
class AnyMonthOfYear(): ListOfInt() { class AnyMonthOfYear(): ListOfInt() {
override fun labelForValue(value: Int): String { override fun labelForValue(value: Int, context: Context): String {
return DateFormatSymbols.getInstance(Locale.getDefault()).months[value] return DateFormatSymbols.getInstance(Locale.getDefault()).months[value]
} }
@ -366,7 +367,7 @@ sealed class QueryCondition : FilterElementRow {
} }
class AnyYear(): ListOfInt() { class AnyYear(): ListOfInt() {
override fun labelForValue(value: Int): String { override fun labelForValue(value: Int, context: Context): String {
return "$value" return "$value"
} }
@ -385,7 +386,7 @@ sealed class QueryCondition : FilterElementRow {
object DuringThisYear: QueryCondition() object DuringThisYear: QueryCondition()
class TournamentFee: ListOfDouble() { class TournamentFee: ListOfDouble() {
override fun labelForValue(value: Double): String { override fun labelForValue(value: Double, context: Context): String {
return value.toCurrency(UserDefaults.currency) return value.toCurrency(UserDefaults.currency)
} }
} }

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import android.content.Context
import io.realm.Realm import io.realm.Realm
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.RealmResults import io.realm.RealmResults
@ -42,7 +43,7 @@ open class Bankroll : RealmObject(), NameManageable, RowRepresentable {
return this.currency?.rate ?: 1.0 return this.currency?.rate ?: 1.0
} }
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return this.name return this.name
} }

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import android.content.Context
import io.realm.Realm import io.realm.Realm
import io.realm.RealmList import io.realm.RealmList
import io.realm.RealmObject import io.realm.RealmObject
@ -48,7 +49,7 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa
// @todo // @todo
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return this.name return this.name
} }

@ -31,7 +31,7 @@ open class CustomFieldEntry : RealmObject(), RowRepresentable {
return context.getString(R.string.value) return context.getString(R.string.value)
} }
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return if (value.isNotEmpty()) value else NULL_TEXT return if (value.isNotEmpty()) value else NULL_TEXT
} }

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import android.content.Context
import io.realm.* import io.realm.*
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where import io.realm.kotlin.where
@ -151,9 +152,8 @@ open class Filter : RealmObject(), RowRepresentable {
return query return query
} }
override fun getDisplayName(context: Context): String {
override fun getDisplayName(): String {
if (name.isNotEmpty()) return name if (name.isNotEmpty()) return name
return this.query.name return this.query.getName(context)
} }
} }

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import android.content.Context
import io.realm.Realm import io.realm.Realm
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
@ -47,7 +48,7 @@ open class Game : RealmObject(), NameManageable, StaticRowRepresentableDataSourc
return this.name return this.name
} }
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return this.name return this.name
} }

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import android.content.Context
import com.google.android.libraries.places.api.model.Place import com.google.android.libraries.places.api.model.Place
import io.realm.Realm import io.realm.Realm
import io.realm.RealmObject import io.realm.RealmObject
@ -30,7 +31,7 @@ open class Location : RealmObject(), NameManageable, RowRepresentable {
// the latitude of the location // the latitude of the location
var latitude: Double? = null var latitude: Double? = null
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return this.name return this.name
} }

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import android.content.Context
import io.realm.RealmList import io.realm.RealmList
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.annotations.Ignore import io.realm.annotations.Ignore
@ -40,7 +41,7 @@ open class ReportSetup : RealmObject(), RowRepresentable {
var filter: Filter? = null var filter: Filter? = null
// RowRepresentable // RowRepresentable
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return this.name return this.name
} }

@ -12,7 +12,10 @@ 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
import net.pokeranalytics.android.calculus.* import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.StatFormattingException
import net.pokeranalytics.android.calculus.TextFormat
import net.pokeranalytics.android.exceptions.ModelException import net.pokeranalytics.android.exceptions.ModelException
import net.pokeranalytics.android.model.Limit import net.pokeranalytics.android.model.Limit
import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.LiveData
@ -572,7 +575,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
@Ignore @Ignore
override val viewType: Int = RowViewType.ROW_SESSION.ordinal override val viewType: Int = RowViewType.ROW_SESSION.ordinal
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return "Session ${this.creationDate}" return "Session ${this.creationDate}"
} }
@ -689,7 +692,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
} }
} }
SessionRow.TOURNAMENT_NAME -> tournamentName?.name ?: NULL_TEXT SessionRow.TOURNAMENT_NAME -> tournamentName?.name ?: NULL_TEXT
else -> throw UnmanagedRowRepresentableException("Unmanaged row = ${row.getDisplayName()}") else -> throw UnmanagedRowRepresentableException("Unmanaged row = ${row}")
} }
} }
@ -922,8 +925,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
// Stat Entry // Stat Entry
override val entryTitle: String override fun entryTitle(context: Context): String {
get() {
return DateFormat.getDateInstance(DateFormat.SHORT).format(this.startDate) return DateFormat.getDateInstance(DateFormat.SHORT).format(this.startDate)
} }
@ -980,7 +982,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
val secondTitle = stat.localizedTitle(context) val secondTitle = stat.localizedTitle(context)
val entryValue = this.formattedValue(stat) val entryValue = this.formattedValue(stat)
val dateValue = TextFormat(this.entryTitle) val dateValue = TextFormat(this.entryTitle(context))
@ -1001,7 +1003,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
} }
} }
DefaultLegendValues(this.entryTitle, left, right) DefaultLegendValues(this.entryTitle(context), left, right)
} }
else -> { else -> {
super.legendValues(stat, entry, style, groupName, context) super.legendValues(stat, entry, style, groupName, context)

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import android.content.Context
import io.realm.Realm import io.realm.Realm
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.RealmResults import io.realm.RealmResults
@ -114,8 +115,7 @@ open class SessionSet() : RealmObject(), Timed, Filterable {
// Stat Base // Stat Base
override val entryTitle: String override fun entryTitle(context: Context): String {
get() {
return DateFormat.getDateInstance(DateFormat.SHORT).format(this.startDate) return DateFormat.getDateInstance(DateFormat.SHORT).format(this.startDate)
} }

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import android.content.Context
import io.realm.Realm import io.realm.Realm
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
@ -38,7 +39,7 @@ open class TournamentFeature : RealmObject(), NameManageable, StaticRowRepresent
// CountableUsage // CountableUsage
override var useCount: Int = 0 override var useCount: Int = 0
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return this.name return this.name
} }

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import android.content.Context
import io.realm.Realm import io.realm.Realm
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
@ -33,7 +34,7 @@ open class TournamentName : RealmObject(), NameManageable, StaticRowRepresentabl
// The name of the tournament // The name of the tournament
override var name: String = "" override var name: String = ""
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return this.name return this.name
} }

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import android.content.Context
import io.realm.Realm import io.realm.Realm
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.annotations.Ignore import io.realm.annotations.Ignore
@ -127,8 +128,7 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo
// GraphUnderlyingEntry // GraphUnderlyingEntry
override val entryTitle: String override fun entryTitle(context: Context): String {
get() {
return DateFormat.getDateInstance(DateFormat.SHORT).format(this.date) return DateFormat.getDateInstance(DateFormat.SHORT).format(this.date)
} }

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import android.content.Context
import io.realm.Realm import io.realm.Realm
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
@ -56,7 +57,7 @@ open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentab
// The predefined kind, if necessary, like: Withdrawal, deposit, or tips // The predefined kind, if necessary, like: Withdrawal, deposit, or tips
var kind: Int? = null var kind: Int? = null
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return this.name return this.name
} }

@ -114,11 +114,12 @@ class HomeActivity : PokerAnalyticsActivity() {
this.currencies = realm.where(Currency::class.java).findAll() this.currencies = realm.where(Currency::class.java).findAll()
this.currencies.addChangeListener { t, _ -> this.currencies.addChangeListener { t, _ ->
realm.beginTransaction() realm.executeTransaction {
t.forEach { t.forEach {
it.refreshRelatedRatedValues() it.refreshRelatedRatedValues()
} }
realm.commitTransaction() }
} }
} }

@ -34,7 +34,7 @@ class ProgressReportActivity : PokerAnalyticsActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_statistic_details) setContentView(R.layout.activity_progress_report)
initUI() initUI()
} }

@ -39,13 +39,11 @@ class TableReportActivity : PokerAnalyticsActivity() {
*/ */
private fun initUI() { private fun initUI() {
report?.let {
val fragmentTransaction = supportFragmentManager.beginTransaction() val fragmentTransaction = supportFragmentManager.beginTransaction()
val fragment = TableReportFragment.newInstance(it) val fragment = TableReportFragment.newInstance(report, reportTitle)
fragmentTransaction.add(R.id.reportDetailsContainer, fragment) fragmentTransaction.add(R.id.reportDetailsContainer, fragment)
fragmentTransaction.commit() fragmentTransaction.commit()
report = null report = null
} }
}
} }

@ -9,7 +9,7 @@ import androidx.viewpager.widget.PagerAdapter
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Report import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.ui.fragment.GraphFragment import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.fragment.report.TableReportFragment import net.pokeranalytics.android.ui.fragment.report.ComposableTableReportFragment
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@ -31,7 +31,7 @@ class ReportPagerAdapter(val context: Context, val fragmentManager: FragmentMana
GraphFragment.newInstance(lineDataSets = dataSetList, style = GraphFragment.Style.MULTILINE) GraphFragment.newInstance(lineDataSets = dataSetList, style = GraphFragment.Style.MULTILINE)
} }
2 -> { 2 -> {
TableReportFragment.newInstance(report) ComposableTableReportFragment.newInstance(report)
} }
else -> PokerAnalyticsFragment() else -> PokerAnalyticsFragment()
} }

@ -6,7 +6,6 @@ import android.os.Bundle
import android.view.* import android.view.*
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_bankroll.* import kotlinx.android.synthetic.main.fragment_bankroll.*
import kotlinx.android.synthetic.main.fragment_stats.recyclerView
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedStat import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.Stat
@ -116,7 +115,7 @@ class BankrollDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable
rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.operations)) rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.operations))
bankrollReport.transactionBuckets.keys.forEach { key -> bankrollReport.transactionBuckets.keys.forEach { key ->
bankrollReport.transactionBuckets[key]?.let { transactionBucket -> bankrollReport.transactionBuckets[key]?.let { transactionBucket ->
val typeName = transactionBucket.transactions.firstOrNull()?.type?.getDisplayName() val typeName = transactionBucket.transactions.firstOrNull()?.type?.getDisplayName(requireContext())
val computedStat = ComputedStat(Stat.NET_RESULT, transactionBucket.total) val computedStat = ComputedStat(Stat.NET_RESULT, transactionBucket.total)
rows.add(CustomizableRowRepresentable(RowViewType.TITLE_VALUE, title = typeName, computedStat = computedStat)) rows.add(CustomizableRowRepresentable(RowViewType.TITLE_VALUE, title = typeName, computedStat = computedStat))
} }

@ -11,7 +11,6 @@ import com.github.mikephil.charting.data.LineDataSet
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.RealmResults import io.realm.RealmResults
import kotlinx.android.synthetic.main.fragment_bankroll.* import kotlinx.android.synthetic.main.fragment_bankroll.*
import kotlinx.android.synthetic.main.fragment_stats.recyclerView
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay

@ -8,7 +8,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import io.realm.Realm import io.realm.Realm
import kotlinx.android.synthetic.main.fragment_calendar.* import kotlinx.android.synthetic.main.fragment_calendar.*
import kotlinx.android.synthetic.main.fragment_stats.recyclerView
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope

@ -1,6 +1,7 @@
package net.pokeranalytics.android.ui.fragment package net.pokeranalytics.android.ui.fragment
import android.app.Activity import android.app.Activity
import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
@ -63,7 +64,7 @@ class CurrenciesFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataS
private class CurrencyRow(var currency:Currency) : RowRepresentable { private class CurrencyRow(var currency:Currency) : RowRepresentable {
override fun getDisplayName(): String { override fun getDisplayName(context: Context): String {
return currency.getDisplayName(Locale.getDefault()).capitalize() return currency.getDisplayName(Locale.getDefault()).capitalize()
} }

@ -5,7 +5,7 @@ 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 kotlinx.android.synthetic.main.fragment_stats.* import kotlinx.android.synthetic.main.fragment_more.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.BankrollActivity import net.pokeranalytics.android.ui.activity.BankrollActivity
import net.pokeranalytics.android.ui.activity.SettingsActivity import net.pokeranalytics.android.ui.activity.SettingsActivity

@ -11,7 +11,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.Realm import io.realm.Realm
import io.realm.RealmResults import io.realm.RealmResults
import kotlinx.android.synthetic.main.fragment_data_list.* import kotlinx.android.synthetic.main.fragment_data_list.*
import kotlinx.android.synthetic.main.fragment_stats.recyclerView
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -75,7 +74,7 @@ class ReportsFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRe
if (requestCode == ReportCreationActivity.RequestCode.NEW_REPORT.ordinal && resultCode == Activity.RESULT_OK) { if (requestCode == ReportCreationActivity.RequestCode.NEW_REPORT.ordinal && resultCode == Activity.RESULT_OK) {
ReportCreationActivity.options?.let { options -> ReportCreationActivity.options?.let { options ->
this.launchReportWithOptions(options, options.defaultName) this.launchReportWithOptions(options, options.getName(requireContext()))
} }
ReportCreationActivity.options = null ReportCreationActivity.options = null
} }

@ -3,12 +3,15 @@ package net.pokeranalytics.android.ui.fragment
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup
import io.realm.Realm import io.realm.Realm
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputableGroup import net.pokeranalytics.android.calculus.ComputableGroup
import net.pokeranalytics.android.calculus.Report import net.pokeranalytics.android.calculus.Report
@ -17,36 +20,29 @@ import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.realm.Filter import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.ui.activity.FiltersActivity import net.pokeranalytics.android.ui.activity.FiltersActivity
import net.pokeranalytics.android.ui.fragment.report.TableReportFragment import net.pokeranalytics.android.ui.fragment.components.ResultsObserverFragment
import net.pokeranalytics.android.ui.fragment.report.ComposableTableReportFragment
import net.pokeranalytics.android.ui.interfaces.FilterActivityRequestCode import net.pokeranalytics.android.ui.interfaces.FilterActivityRequestCode
import net.pokeranalytics.android.ui.interfaces.FilterHandler import net.pokeranalytics.android.ui.interfaces.FilterHandler
import net.pokeranalytics.android.ui.interfaces.FilterableType import net.pokeranalytics.android.ui.interfaces.FilterableType
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.StatRow
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
class StatisticsFragment : TableReportFragment(), FilterHandler { class StatisticsFragment : ResultsObserverFragment(), FilterHandler {
override val coroutineContext: CoroutineContext val coroutineContext: CoroutineContext
get() = Dispatchers.Main get() = Dispatchers.Main
private var stringAll = "" private lateinit var tableReportFragment: ComposableTableReportFragment
private var stringCashGame = ""
private var stringTournament = ""
companion object { companion object {
/** /**
* Create new instance * Create new instance
*/ */
fun newInstance(report: Report? = null): StatisticsFragment { fun newInstance(): StatisticsFragment {
val fragment = StatisticsFragment() val fragment = StatisticsFragment()
report?.let {
fragment.report = it
}
val bundle = Bundle() val bundle = Bundle()
fragment.arguments = bundle fragment.arguments = bundle
return fragment return fragment
@ -55,26 +51,39 @@ class StatisticsFragment : TableReportFragment(), FilterHandler {
// Life Cycle // Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_stats, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
initUI()
launchStatComputation() launchStatComputation()
} }
private fun initUI() {
val fragmentTransaction = requireFragmentManager().beginTransaction()
val fragment = ComposableTableReportFragment.newInstance(null)
fragmentTransaction.add(R.id.tableContainer, fragment)
fragmentTransaction.commit()
this.tableReportFragment = fragment
}
override fun sessionsChanged() { override fun sessionsChanged() {
this.launchStatComputation() this.launchStatComputation()
this.statsAdapter?.notifyDataSetChanged()
} }
override fun convertReportIntoRepresentables(report: Report): ArrayList<RowRepresentable> { // override fun convertReportIntoRepresentables(report: Report): ArrayList<RowRepresentable> {
val rows: ArrayList<RowRepresentable> = ArrayList() // val rows: ArrayList<RowRepresentable> = ArrayList()
report.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(StatRow(stat, result.computedStat(stat), result.group.name)) // rows.add(StatRow(stat, result.computedStat(stat), result.group.name))
} // }
} // }
return rows // return rows
} // }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
@ -114,7 +123,10 @@ class StatisticsFragment : TableReportFragment(), FilterHandler {
Timber.d(">>> start...") Timber.d(">>> start...")
val realm = Realm.getDefaultInstance() val realm = Realm.getDefaultInstance()
report = createSessionGroupsAndStartCompute(realm)
val report = createSessionGroupsAndStartCompute(realm)
tableReportFragment.report = report
realm.close() realm.close()
val e = Date() val e = Date()
@ -125,7 +137,7 @@ class StatisticsFragment : TableReportFragment(), FilterHandler {
test.await() test.await()
if (!isDetached) { if (!isDetached) {
showResults() tableReportFragment.showResults()
} }
} }
} }
@ -146,7 +158,7 @@ class StatisticsFragment : TableReportFragment(), FilterHandler {
Stat.HOURLY_DURATION Stat.HOURLY_DURATION
) )
val query = filter?.query ?: run { Query() } val query = filter?.query ?: Query()
val allSessionGroup = ComputableGroup(query, allStats) val allSessionGroup = ComputableGroup(query, allStats)
val cgStats: List<Stat> = listOf( val cgStats: List<Stat> = listOf(

@ -1,17 +1,23 @@
package net.pokeranalytics.android.ui.fragment.report package net.pokeranalytics.android.ui.fragment.report
import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Report import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.ui.fragment.components.RealmFragment
abstract class AbstractReportFragment : RealmFragment() { abstract class AbstractReportFragment : RealmFragment() {
protected lateinit var selectedReport: Report protected lateinit var selectedReport: Report
protected var reportTitle: String? = null
private var editableMenu: Menu? = null private var editableMenu: Menu? = null
protected lateinit var parentActivity: PokerAnalyticsActivity
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
menu?.clear() menu?.clear()
@ -28,6 +34,11 @@ abstract class AbstractReportFragment : RealmFragment() {
return true return true
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
parentActivity = activity as PokerAnalyticsActivity
}
/** /**
* Update menu UI * Update menu UI
*/ */

@ -5,13 +5,10 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import kotlinx.android.synthetic.main.fragment_report_details.*
import kotlinx.android.synthetic.main.fragment_progress_report.toolbar import kotlinx.android.synthetic.main.fragment_progress_report.toolbar
import kotlinx.android.synthetic.main.fragment_report_details.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.AggregationType
import net.pokeranalytics.android.calculus.Report import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.adapter.ReportPagerAdapter import net.pokeranalytics.android.ui.adapter.ReportPagerAdapter
class ComparisonReportFragment : AbstractReportFragment() { class ComparisonReportFragment : AbstractReportFragment() {
@ -30,12 +27,16 @@ class ComparisonReportFragment : AbstractReportFragment() {
} }
} }
private lateinit var parentActivity: PokerAnalyticsActivity // private var reports: MutableMap<AggregationType, Report> = hashMapOf()
// private var stat: Stat = Stat.NET_RESULT
// private var displayAggregationChoices: Boolean = true
private var reports: MutableMap<AggregationType, Report> = hashMapOf() /**
private var stat: Stat = Stat.NET_RESULT * Set data
private var displayAggregationChoices: Boolean = true */
private var reportTitle: String = "" fun setData(report: Report) {
this.selectedReport = report
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState) super.onCreateView(inflater, container, savedInstanceState)
@ -52,8 +53,6 @@ class ComparisonReportFragment : AbstractReportFragment() {
*/ */
private fun initUI() { private fun initUI() {
parentActivity = activity as PokerAnalyticsActivity
// Avoid a bug during setting the titleResId // Avoid a bug during setting the titleResId
toolbar.title = "" toolbar.title = ""
@ -80,12 +79,4 @@ class ComparisonReportFragment : AbstractReportFragment() {
}) })
} }
/**
* Set data
*/
fun setData(report: Report) {
this.selectedReport = report
}
} }

@ -0,0 +1,221 @@
package net.pokeranalytics.android.ui.fragment.report
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.Realm
import kotlinx.android.synthetic.main.fragment_composable_table_report.*
import kotlinx.coroutines.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.*
import net.pokeranalytics.android.model.realm.ComputableResult
import net.pokeranalytics.android.ui.activity.ProgressReportActivity
import net.pokeranalytics.android.ui.adapter.DisplayDescriptor
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.StatRow
import net.pokeranalytics.android.util.NULL_TEXT
import timber.log.Timber
import java.util.*
import kotlin.coroutines.CoroutineContext
open class ComposableTableReportFragment : RealmFragment(), StaticRowRepresentableDataSource, CoroutineScope,
RowRepresentableDelegate {
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main
private var rowRepresentables: ArrayList<RowRepresentable> = ArrayList()
var statsAdapter: RowRepresentableAdapter? = null
var report: Report? = null
companion object {
/**
* Create new instance
*/
fun newInstance(report: Report? = null): ComposableTableReportFragment {
val fragment = ComposableTableReportFragment()
fragment.report = report
val bundle = Bundle()
fragment.arguments = bundle
return fragment
}
}
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_composable_table_report, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initData()
initUI()
report?.let {
showResults()
}
}
// Row Representable DS
override fun adapterRows(): List<RowRepresentable>? {
return this.rowRepresentables
}
override fun contentDescriptorForRow(row: RowRepresentable): DisplayDescriptor? {
val dc = DisplayDescriptor()
dc.textFormat = TextFormat(NULL_TEXT)
if (row is StatRow) {
context?.let { _ ->
row.computedStat?.let {
dc.textFormat = it.format()
}
}
}
return dc
}
override fun statFormatForRow(row: RowRepresentable): TextFormat {
if (row is StatRow) {
context?.let { _ ->
row.computedStat?.let { return it.format() }
}
}
return TextFormat(NULL_TEXT)
}
override fun onResume() {
super.onResume()
statsAdapter?.notifyDataSetChanged()
}
// Business
/**
* Init data
*/
open fun initData() {
this.statsAdapter = RowRepresentableAdapter(this, this)
}
/**
* Init UI
*/
open fun initUI() {
val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = statsAdapter
}
}
/**
* Show results
*/
fun showResults() {
report?.let {
this.rowRepresentables = this.convertReportIntoRepresentables(it)
statsAdapter?.notifyDataSetChanged()
}
}
open fun convertReportIntoRepresentables(report: Report): ArrayList<RowRepresentable> {
val rows: ArrayList<RowRepresentable> = ArrayList()
report.results.forEach { result ->
val title = result.group.query.getName(requireContext()).capitalize()
rows.add(CustomizableRowRepresentable(title = title))
val statList = result.group.stats ?: report.options.stats
statList.forEach { stat ->
rows.add(StatRow(stat, result.computedStat(stat), result.group.query.getName(requireContext())))
}
}
return rows
// val rows: ArrayList<RowRepresentable> = ArrayList()
// report.options.stats.forEach {stat ->
// rows.add(CustomizableRowRepresentable(title = stat.localizedTitle(requireContext())))
// report.results.forEach {
// val title = it.group.name
// rows.add(StatRow(stat, it.computedStat(stat), it.group.name, title))
// }
// }
// return rows
}
// RowRepresentableDelegate
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
val cr = getRealm().where(ComputableResult::class.java).findAll()
if (cr.size < 2) {
Toast.makeText(context, R.string.less_then_2_values_for_display, Toast.LENGTH_LONG).show()
return
}
if (row is StatRow && row.stat.hasProgressGraph) {
// queryWith groups
val groupResults = this.report?.results?.filter {
row.groupName == it.group.query.getName(requireContext())
}
groupResults?.firstOrNull()?.let {
this.launchStatComputationWithEvolution(row.stat, it.group)
}
}
}
private fun launchStatComputationWithEvolution(stat: Stat, computableGroup: ComputableGroup) {
showLoader()
GlobalScope.launch(coroutineContext) {
var report: Report? = null
val test = GlobalScope.async {
val s = Date()
Timber.d(">>> start...")
val realm = Realm.getDefaultInstance()
val aggregationType = stat.aggregationTypes.first()
report =
Calculator.computeStatsWithEvolutionByAggregationType(realm, stat, computableGroup, aggregationType)
realm.close()
val e = Date()
val duration = (e.time - s.time) / 1000.0
Timber.d(">>> ended in $duration seconds")
}
test.await()
if (!isDetached) {
hideLoader()
report?.let {
ProgressReportActivity.newInstance(requireContext(), stat, it)
}
}
}
}
}

@ -21,7 +21,6 @@ import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.Report import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.model.combined import net.pokeranalytics.android.model.combined
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.extensions.ChipGroupExtension import net.pokeranalytics.android.ui.extensions.ChipGroupExtension
import net.pokeranalytics.android.ui.extensions.hideWithAnimation import net.pokeranalytics.android.ui.extensions.hideWithAnimation
import net.pokeranalytics.android.ui.extensions.px import net.pokeranalytics.android.ui.extensions.px
@ -46,10 +45,8 @@ class ProgressReportFragment : AbstractReportFragment() {
} }
} }
private lateinit var parentActivity: PokerAnalyticsActivity
private lateinit var graphFragment: GraphFragment private lateinit var graphFragment: GraphFragment
private var title: String? = null
private var reports: MutableMap<AggregationType, Report> = hashMapOf() private var reports: MutableMap<AggregationType, Report> = hashMapOf()
private var stat: Stat = Stat.NET_RESULT private var stat: Stat = Stat.NET_RESULT
private var displayAggregationChoices: Boolean = true private var displayAggregationChoices: Boolean = true
@ -71,7 +68,7 @@ class ProgressReportFragment : AbstractReportFragment() {
this.stat = stat this.stat = stat
this.selectedReport = report this.selectedReport = report
this.displayAggregationChoices = displayAggregationChoices this.displayAggregationChoices = displayAggregationChoices
this.title = title this.reportTitle = title
stat.aggregationTypes.firstOrNull()?.let { stat.aggregationTypes.firstOrNull()?.let {
reports[it] = report reports[it] = report
@ -83,8 +80,6 @@ class ProgressReportFragment : AbstractReportFragment() {
*/ */
private fun initUI() { private fun initUI() {
parentActivity = activity as PokerAnalyticsActivity
// Avoid a bug during setting the titleResId // Avoid a bug during setting the titleResId
toolbar.title = "" toolbar.title = ""
@ -105,7 +100,7 @@ class ProgressReportFragment : AbstractReportFragment() {
} }
} }
toolbar.title = this.title ?: stat.localizedTitle(requireContext()) toolbar.title = this.reportTitle ?: stat.localizedTitle(requireContext())
val aggregationTypes = stat.aggregationTypes val aggregationTypes = stat.aggregationTypes
aggregationTypes.forEachIndexed { index, type -> aggregationTypes.forEachIndexed { index, type ->

@ -4,48 +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 android.widget.Toast import kotlinx.android.synthetic.main.fragment_progress_report.*
import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.Realm
import kotlinx.android.synthetic.main.fragment_stats.*
import kotlinx.coroutines.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.* import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.model.realm.ComputableResult
import net.pokeranalytics.android.ui.activity.ProgressReportActivity
import net.pokeranalytics.android.ui.adapter.DisplayDescriptor
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.fragment.components.ResultsObserverFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.StatRow
import net.pokeranalytics.android.util.NULL_TEXT
import timber.log.Timber
import java.util.*
import kotlin.coroutines.CoroutineContext
open class TableReportFragment : ResultsObserverFragment(), StaticRowRepresentableDataSource, CoroutineScope, class TableReportFragment : AbstractReportFragment() {
RowRepresentableDelegate {
override val coroutineContext: CoroutineContext private lateinit var tableReportFragment: ComposableTableReportFragment
get() = Dispatchers.Main
private var rowRepresentables: ArrayList<RowRepresentable> = ArrayList()
var statsAdapter: RowRepresentableAdapter? = null
var report : Report? = null
companion object { companion object {
/** /**
* Create new instance * Create new instance
*/ */
fun newInstance(report: Report? = null): TableReportFragment { fun newInstance(report: Report? = null, title: String? = null): TableReportFragment {
val fragment = TableReportFragment() val fragment = TableReportFragment()
fragment.reportTitle = title
report?.let { report?.let {
fragment.report = it fragment.selectedReport = it
} }
val bundle = Bundle() val bundle = Bundle()
fragment.arguments = bundle fragment.arguments = bundle
@ -53,156 +29,34 @@ open class TableReportFragment : ResultsObserverFragment(), StaticRowRepresentab
} }
} }
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState) super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_stats, container, false) return inflater.inflate(R.layout.fragment_table_report, container, false)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
initData()
initUI() initUI()
report?.let {
showResults()
}
} }
// Row Representable DS private fun initUI() {
override fun adapterRows(): List<RowRepresentable>? { // Avoid a bug during setting the titleResId
return this.rowRepresentables toolbar.title = ""
}
override fun contentDescriptorForRow(row: RowRepresentable): DisplayDescriptor? { parentActivity.setSupportActionBar(toolbar)
val dc = DisplayDescriptor() parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
dc.textFormat = TextFormat(NULL_TEXT) setHasOptionsMenu(true)
if (row is StatRow) {
context?.let { _ ->
row.computedStat?.let {
dc.textFormat = it.format()
}
}
}
return dc
}
override fun statFormatForRow(row: RowRepresentable): TextFormat { toolbar.title = reportTitle
if (row is StatRow) {
context?.let { _ ->
row.computedStat?.let { return it.format() }
}
}
return TextFormat(NULL_TEXT)
}
override fun onResume() { val fragmentTransaction = parentActivity.supportFragmentManager.beginTransaction()
super.onResume() val fragment = ComposableTableReportFragment.newInstance(this.selectedReport)
statsAdapter?.notifyDataSetChanged() fragmentTransaction.add(R.id.tableReportContainer, fragment)
} fragmentTransaction.commit()
// Business this.tableReportFragment = fragment
/**
* Init data
*/
open fun initData() {
this.statsAdapter = RowRepresentableAdapter(this, this)
}
/**
* Init UI
*/
open fun initUI() {
val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = statsAdapter
}
}
/**
* Show results
*/
fun showResults() {
report?.let {
this.rowRepresentables = this.convertReportIntoRepresentables(it)
statsAdapter?.notifyDataSetChanged()
}
}
open fun convertReportIntoRepresentables(report: Report): ArrayList<RowRepresentable> {
val rows: ArrayList<RowRepresentable> = ArrayList()
report.options.stats.forEach {stat ->
rows.add(CustomizableRowRepresentable(title = stat.localizedTitle(requireContext())))
report.results.forEach {
val title = it.group.name
rows.add(StatRow(stat, it.computedStat(stat), it.group.name, title))
}
}
return rows
}
// RowRepresentableDelegate
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
val cr = getRealm().where(ComputableResult::class.java).findAll()
if (cr.size < 2) {
Toast.makeText(context, R.string.less_then_2_values_for_display, Toast.LENGTH_LONG).show()
return
}
if (row is StatRow && row.stat.hasProgressGraph) {
// queryWith groups
val groupResults = this.report?.results?.filter {
it.group.name == row.groupName
}
groupResults?.firstOrNull()?.let {
this.launchStatComputationWithEvolution(row.stat, it.group)
}
}
}
private fun launchStatComputationWithEvolution(stat: Stat, computableGroup: ComputableGroup) {
showLoader()
GlobalScope.launch(coroutineContext) {
var report: Report? = null
val test = GlobalScope.async {
val s = Date()
Timber.d(">>> start...")
val realm = Realm.getDefaultInstance()
val aggregationType = stat.aggregationTypes.first()
report = Calculator.computeStatsWithEvolutionByAggregationType(realm, stat, computableGroup, aggregationType)
realm.close()
val e = Date()
val duration = (e.time - s.time) / 1000.0
Timber.d(">>> ended in $duration seconds")
}
test.await()
if (!isDetached) {
hideLoader()
report?.let {
ProgressReportActivity.newInstance(requireContext(), stat, it)
}
}
}
} }
} }

@ -15,7 +15,7 @@ class ObjectIdentifier(var id: String, var clazz: Class<out Timed>) {
interface GraphUnderlyingEntry { interface GraphUnderlyingEntry {
val entryTitle: String fun entryTitle(context: Context): String
fun formattedValue(stat: Stat): TextFormat fun formattedValue(stat: Stat): TextFormat
fun legendValues( fun legendValues(
@ -29,12 +29,12 @@ interface GraphUnderlyingEntry {
return when (stat) { return when (stat) {
Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_GAMES, Stat.WIN_RATIO, Stat.HOURLY_DURATION, Stat.AVERAGE_HOURLY_DURATION -> { Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_GAMES, Stat.WIN_RATIO, Stat.HOURLY_DURATION, Stat.AVERAGE_HOURLY_DURATION -> {
val totalStatValue = stat.format(entry.y.toDouble(), currency = null) val totalStatValue = stat.format(entry.y.toDouble(), currency = null)
DefaultLegendValues(this.entryTitle, totalStatValue) DefaultLegendValues(this.entryTitle(context), totalStatValue)
} }
else -> { else -> {
val entryValue = this.formattedValue(stat) val entryValue = this.formattedValue(stat)
val totalStatValue = stat.format(entry.y.toDouble(), currency = null) val totalStatValue = stat.format(entry.y.toDouble(), currency = null)
DefaultLegendValues(this.entryTitle, entryValue, totalStatValue) DefaultLegendValues(this.entryTitle(context), entryValue, totalStatValue)
} }
} }

@ -10,7 +10,7 @@ import net.pokeranalytics.android.util.NULL_TEXT
*/ */
interface RowRepresentable : Displayable, EditDataSource, ImageDecorator { interface RowRepresentable : Displayable, EditDataSource, ImageDecorator {
fun getDisplayName(): String { fun getDisplayName(context: Context): String {
return NULL_TEXT return NULL_TEXT
} }
} }

@ -175,7 +175,7 @@ enum class RowViewType(private var layoutRes: Int) {
if (row.resId != null) { if (row.resId != null) {
it.text = row.localizedTitle(itemView.context) it.text = row.localizedTitle(itemView.context)
} else { } else {
it.text = row.getDisplayName() it.text = row.getDisplayName(itemView.context)
} }
} }

@ -0,0 +1,17 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
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_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -2,12 +2,11 @@
<androidx.constraintlayout.widget.ConstraintLayout <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" xmlns:app="http://schemas.android.com/apk/res-auto"
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">
<androidx.recyclerview.widget.RecyclerView <FrameLayout
android:id="@+id/recyclerView" android:id="@+id/tableContainer"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
@ -15,4 +14,13 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<!--<androidx.recyclerview.widget.RecyclerView-->
<!--android:id="@+id/recyclerView"-->
<!--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_toTopOf="parent" />-->
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,27 @@
<?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_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:title="@string/app_name" />
<FrameLayout
android:id="@+id/tableReportContainer"
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>
Loading…
Cancel
Save