From 45e61d9a460675c6aed2ea4f36ebc3f88464d69a Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 28 Feb 2019 15:26:54 +0100 Subject: [PATCH] Stat formatting + Preferences --- .../pokeranalytics/android/calculus/Format.kt | 11 +++- .../pokeranalytics/android/calculus/Stat.kt | 51 +++++++++++++++++-- .../{ModelException.kt => Exceptions.kt} | 4 ++ .../ui/adapter/RowRepresentableDataSource.kt | 9 +++- .../android/ui/fragment/StatsFragment.kt | 20 ++++++-- .../android/ui/view/RowViewType.kt | 4 +- .../android/util/NumbersExtension.kt | 7 +++ .../android/util/Preferences.kt | 41 +++++++++++++++ 8 files changed, 134 insertions(+), 13 deletions(-) rename app/src/main/java/net/pokeranalytics/android/exceptions/{ModelException.kt => Exceptions.kt} (61%) create mode 100644 app/src/main/java/net/pokeranalytics/android/util/Preferences.kt diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Format.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Format.kt index 79531e93..1a99b722 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Format.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Format.kt @@ -1,8 +1,15 @@ package net.pokeranalytics.android.calculus +import android.content.Context import android.graphics.Color +import androidx.core.content.ContextCompat -class StatFormat(text: String, color: Int = Color.WHITE) { +class TextFormat(text: String, color: Int? = null) { var text: String = text - var color: Int = color + private var color: Int? = color + + fun getColor(context: Context) : Int { + this.color?.let { return ContextCompat.getColor(context, it) } + return Color.WHITE + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt index eaabcf1b..e9a86553 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt @@ -1,8 +1,15 @@ package net.pokeranalytics.android.calculus +import android.content.Context import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.FormattingException import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType +import net.pokeranalytics.android.util.Preferences +import net.pokeranalytics.android.util.formatted +import net.pokeranalytics.android.util.toMinutes +import java.text.NumberFormat +import java.util.* /** * An enum representing all the types of Session statistics @@ -72,6 +79,15 @@ enum class Stat : RowRepresentable { } } + val threshold: Double + get() { + return when (this) { + WIN_RATIO -> 50.0 + else -> 0.0 + } + + } + override val viewType: Int = RowViewType.TITLE_VALUE.ordinal override var displayHeader: Boolean = false override var headerValues: ArrayList = ArrayList() @@ -106,15 +122,40 @@ class ComputedStat(stat: Stat, value: Double) { /** * Formats the value of the stat to be suitable for display */ - fun format() : StatFormat { - return StatFormat("${value}".toUpperCase()) + fun format(context: Context) : TextFormat { + when (this.stat) { + // Amounts + red/green + Stat.NETRESULT, Stat.HOURLY_RATE, Stat.AVERAGE, Stat.NET_BB_PER_100_HANDS, Stat.HOURLY_RATE_BB, + Stat.AVERAGE_NET_BB -> { + val numberFormat = NumberFormat.getCurrencyInstance(Preferences.getCurrencyLocale(context)) + val color = if (this.value >= this.stat.threshold) R.color.green else R.color.red + return TextFormat(numberFormat.format(this.value), color) + } // white integers + Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_GAMES, Stat.HANDS_PLAYED -> { + return TextFormat("${this.value.toInt()}") + } // white durations + Stat.DURATION, Stat.AVERAGE_DURATION -> { + return TextFormat("${this.value.toLong().toMinutes()}") + } // red/green percentages + Stat.WIN_RATIO, Stat.ROI -> { + val color = if (this.value >= this.stat.threshold) R.color.green else R.color.red + return TextFormat("${this.value.formatted()}%", color) + } // white amounts + Stat.AVERAGE_BUYIN, Stat.STANDARD_DEVIATION, Stat.STANDARD_DEVIATION_HOURLY, + Stat.STANDARD_DEVIATION_BB_PER_100_HANDS -> { + val numberFormat = NumberFormat.getCurrencyInstance(Preferences.getCurrencyLocale(context)) + return TextFormat(numberFormat.format(this.value)) + } + else -> throw FormattingException("Stat formatting of ${this.stat.name} not handled") + } + } /** - * Returns a StatFormat instance for an evolution value located at the specified [index] + * Returns a TextFormat instance for an evolution value located at the specified [index] */ - fun evolutionValueFormat(index: Int) : StatFormat { - return StatFormat("undef") + fun evolutionValueFormat(index: Int) : TextFormat { + return TextFormat("undef") } } diff --git a/app/src/main/java/net/pokeranalytics/android/exceptions/ModelException.kt b/app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt similarity index 61% rename from app/src/main/java/net/pokeranalytics/android/exceptions/ModelException.kt rename to app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt index 3c54666a..3f6d1e29 100644 --- a/app/src/main/java/net/pokeranalytics/android/exceptions/ModelException.kt +++ b/app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt @@ -2,4 +2,8 @@ package net.pokeranalytics.android.exceptions class ModelException(message: String) : Exception(message) { +} + +class FormattingException(message: String) : Exception(message) { + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt index c15b90f1..2500af71 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt @@ -1,10 +1,10 @@ package net.pokeranalytics.android.ui.adapter import android.content.Context +import net.pokeranalytics.android.calculus.TextFormat import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor - interface RowRepresentableDataSource : DisplayableDataSource { fun rowRepresentableForPosition(position:Int): RowRepresentable { @@ -74,6 +74,13 @@ interface DisplayableDataSource { return "" } + /** + * Returns a string for a specific row + */ + fun statFormatForRow(row: RowRepresentable): TextFormat { + return TextFormat("you should override this") + } + /** * Returns an action icon identifier for a specific row */ diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatsFragment.kt index c188f4b3..244af97b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatsFragment.kt @@ -12,6 +12,7 @@ import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.ComputedResults import net.pokeranalytics.android.calculus.SessionGroup +import net.pokeranalytics.android.calculus.TextFormat import net.pokeranalytics.android.model.StatRepresentable import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter @@ -57,14 +58,25 @@ class StatsFragment : PokerAnalyticsFragment(), RowRepresentableDataSource { return this.rowRepresentables } - override fun stringForRow(row: RowRepresentable): String { + override fun statFormatForRow(row: RowRepresentable): TextFormat { if (row is StatRepresentable) { - val format = row.computedStat.format() - return format.text + context?.let { + return row.computedStat.format(it) + } } - return "shouldn't happen :)" + return TextFormat("shouldn't happen :)") } +// override fun stringForRow(row: RowRepresentable): String { +// if (row is StatRepresentable) { +// context?.let { +// val format = row.computedStat.format(it) +// return format.text +// } +// } +// return "shouldn't happen :)" +// } + /** * Init data */ diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt index badf2572..e09bb440 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt @@ -208,7 +208,9 @@ enum class RowViewType { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) { itemView.rowStatsTitleValue_title.text = row.localizedTitle(itemView.context) adapter.dataSource?.let { - itemView.rowStatsTitleValue_value.text = it.stringForRow(row, itemView.context) + val format = it.statFormatForRow(row) + itemView.rowStatsTitleValue_value.text = format.text + itemView.rowStatsTitleValue_value.setTextColor(format.getColor(itemView.context)) } val listener = View.OnClickListener { adapter.delegate?.onRowSelected(position, row) diff --git a/app/src/main/java/net/pokeranalytics/android/util/NumbersExtension.kt b/app/src/main/java/net/pokeranalytics/android/util/NumbersExtension.kt index 98abbb80..40ca65f8 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/NumbersExtension.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/NumbersExtension.kt @@ -11,6 +11,13 @@ fun Double.round(): String { return formatter.format(this) } +fun Double.formatted(): String { + val format = NumberFormat.getNumberInstance() + format.maximumFractionDigits = 2 + format.minimumFractionDigits = 0 + return format.format(this) +} + fun Double.toCurrency(): String { val format = NumberFormat.getCurrencyInstance() format.maximumFractionDigits = 2 diff --git a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt new file mode 100644 index 00000000..a283f7dc --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt @@ -0,0 +1,41 @@ +package net.pokeranalytics.android.util + +import android.content.Context +import android.preference.PreferenceManager +import java.util.* + +class Preferences { + + enum class Keys(identifier: String) { + CURRENCY_LANGUAGE("CurrencyLanguage") + } + + companion object { + + fun setString(key: Keys, value: String, context: Context) { + var preferences = PreferenceManager.getDefaultSharedPreferences(context) + var editor = preferences.edit() + editor.putString(key.toString(), value) + editor.commit() + } + + fun getString(key: Keys, context: Context) : String? { + var preferences = PreferenceManager.getDefaultSharedPreferences(context) + return preferences.getString(key.name, null) + } + + fun setCurrencyLanguage(language: String, context: Context) { + Preferences.setString(Keys.CURRENCY_LANGUAGE, language, context) + } + + fun getCurrencyLocale(context : Context) : Locale { + val currencyLanguage = Preferences.getString(Keys.CURRENCY_LANGUAGE, context) + if (currencyLanguage != null) { + return Locale(currencyLanguage) + } + return Locale.getDefault() + } + + } + +} \ No newline at end of file