Fixes various problems

filterfix
Laurent 5 years ago
parent b7613644c6
commit c358d4131f
  1. 4
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/RealmFilterInstrumentedUnitTest.kt
  2. 102
      app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt
  3. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt
  4. 6
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterDetailsFragment.kt
  5. 3
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterDetailsViewModel.kt
  6. 64
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterItemRow.kt

@ -5,7 +5,7 @@ import net.pokeranalytics.android.components.BaseFilterInstrumentedUnitTest
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.model.realm.Session import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.view.rowrepresentable.BaseFilterItemRow import net.pokeranalytics.android.ui.view.rowrepresentable.FixedValueFilterItemRow
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow
import org.junit.Assert import org.junit.Assert
@ -25,7 +25,7 @@ class RealmFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
filter.name = "testSaveLoadCashFilter" filter.name = "testSaveLoadCashFilter"
val filterElement = QueryCondition.IsCash val filterElement = QueryCondition.IsCash
val filterItemRow = BaseFilterItemRow(filterElement, FilterSectionRow.CashOrTournament) val filterItemRow = FixedValueFilterItemRow(filterElement, FilterSectionRow.CashOrTournament)
filter.createOrUpdateFilterConditions(arrayListOf(filterItemRow)) filter.createOrUpdateFilterConditions(arrayListOf(filterItemRow))

@ -31,7 +31,6 @@ import kotlin.reflect.KClass
* Enum describing the way a query should be handled * Enum describing the way a query should be handled
* Some queries requires a value to be checked upon through equals, in, more, less, between * Some queries requires a value to be checked upon through equals, in, more, less, between
*/ */
sealed class QueryCondition : RowRepresentable { sealed class QueryCondition : RowRepresentable {
companion object { companion object {
@ -177,9 +176,23 @@ sealed class QueryCondition : RowRepresentable {
} }
abstract class SingleValue<T>(value: T) : ListOfValues<T>() where T : Comparable<T> { abstract class SingleValue<T>(value: T) : QueryCondition() where T : Comparable<T> {
override var listOfValues = mutableListOf<T>() // override var listOfValues = mutableListOf<T>()
var singleValue: T = value var singleValue: T = value
abstract fun labelForValue(value: T, context: Context): String
override fun getDisplayName(context: Context): String {
return getDisplayName(context, singleValue)
}
fun getDisplayName(context: Context, value: T): String {
val prefix = this.resId?.let {
context.getString(it) + " "
} ?: ""
return prefix + labelForValue(value, context)
}
} }
abstract class ListOfDouble : ListOfValues<Double>() { abstract class ListOfDouble : ListOfValues<Double>() {
@ -194,10 +207,6 @@ sealed class QueryCondition : RowRepresentable {
override fun labelForValue(value: Double, context: Context): String { override fun labelForValue(value: Double, context: Context): String {
return value.toCurrency(UserDefaults.currency) return value.toCurrency(UserDefaults.currency)
} }
override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return DoubleValueListFilterItemRow(this, filterSectionRow)
}
} }
abstract class ListOfInt : ListOfValues<Int>() { abstract class ListOfInt : ListOfValues<Int>() {
@ -211,7 +220,9 @@ sealed class QueryCondition : RowRepresentable {
override fun labelForValue(value: Int, context: Context): String { override fun labelForValue(value: Int, context: Context): String {
return value.toString() return value.toString()
} }
}
abstract class UserInputListOfInt : ListOfInt() {
override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow { override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return IntValueListFilterItemRow(this, filterSectionRow) return IntValueListFilterItemRow(this, filterSectionRow)
} }
@ -228,10 +239,6 @@ sealed class QueryCondition : RowRepresentable {
super.updateValueBy(filterCondition) super.updateValueBy(filterCondition)
listOfValues = filterCondition.getValues() listOfValues = filterCondition.getValues()
} }
override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return StringValueListFilterItemRow(this, filterSectionRow)
}
} }
abstract class SingleDate(date: Date) : SingleValue<Date>(date) { abstract class SingleDate(date: Date) : SingleValue<Date>(date) {
@ -239,7 +246,7 @@ sealed class QueryCondition : RowRepresentable {
return value.shortDate() return value.shortDate()
} }
override var listOfValues = mutableListOf<Date>() // override var listOfValues = mutableListOf<Date>()
override fun updateValueBy(filterCondition: FilterCondition) { override fun updateValueBy(filterCondition: FilterCondition) {
super.updateValueBy(filterCondition) super.updateValueBy(filterCondition)
@ -261,6 +268,9 @@ sealed class QueryCondition : RowRepresentable {
singleValue = filterCondition.getValue() singleValue = filterCondition.getValue()
} }
}
abstract class UserInputSingleInt(value: Int) : SingleInt(value) {
override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow { override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return IntFilterItemRow(this, filterSectionRow) return IntFilterItemRow(this, filterSectionRow)
} }
@ -307,12 +317,11 @@ sealed class QueryCondition : RowRepresentable {
} }
} }
interface DateTime { interface DateTime {
val showTime: Boolean val showTime: Boolean
} }
abstract class DateQuery(date: Date) : SingleDate(date), DateTime { abstract class DateQuery(date: Date) : UserInputSingleDate(date), DateTime {
override val showTime: Boolean = false override val showTime: Boolean = false
override fun labelForValue(value: Date, context: Context): String { override fun labelForValue(value: Date, context: Context): String {
@ -324,6 +333,12 @@ sealed class QueryCondition : RowRepresentable {
} }
} }
abstract class UserInputSingleDate(date: Date) : SingleDate(date) {
override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return DateFilterItemRow(this, filterSectionRow)
}
}
abstract class TimeQuery(date: Date) : DateQuery(date) { abstract class TimeQuery(date: Date) : DateQuery(date) {
override val showTime: Boolean = true override val showTime: Boolean = true
} }
@ -446,15 +461,12 @@ sealed class QueryCondition : RowRepresentable {
override fun entityName(context: Context): String { override fun entityName(context: Context): String {
return context.getString(R.string.blinds) return context.getString(R.string.blinds)
} }
override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return FixedValueFilterItemRow(this, filterSectionRow)
} }
// object Last : SingleInt() { }
// override var operator = Operator.EQUALS
// override fun getDisplayName(context: Context): String {
// //TODO update string "last %i"
// return "${context.getString(R.string.last_i_records)} $singleValue"
// }
// }
class NumberOfTable : ListOfInt() { class NumberOfTable : ListOfInt() {
override fun labelForValue(value: Int, context: Context): String { override fun labelForValue(value: Int, context: Context): String {
@ -466,7 +478,13 @@ sealed class QueryCondition : RowRepresentable {
} }
} }
class NumberOfRebuy() : ListOfDouble() { open class UserInputListOfDouble : ListOfDouble() {
override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return DoubleValueListFilterItemRow(this, filterSectionRow)
}
}
class NumberOfRebuy() : UserInputListOfDouble() {
constructor(operator: Operator, numberOfRebuy: Double) : this() { constructor(operator: Operator, numberOfRebuy: Double) : this() {
this.operator = operator this.operator = operator
this.listOfValues = arrayListOf(numberOfRebuy) this.listOfValues = arrayListOf(numberOfRebuy)
@ -477,20 +495,20 @@ sealed class QueryCondition : RowRepresentable {
} }
} }
class TournamentFinalPosition() : ListOfInt() { class TournamentFinalPosition() : UserInputListOfInt() {
constructor(operator: Operator, finalPosition: Int) : this() { constructor(operator: Operator, finalPosition: Int) : this() {
this.operator = operator this.operator = operator
this.listOfValues = arrayListOf(finalPosition) this.listOfValues = arrayListOf(finalPosition)
} }
override fun labelForValue(value: Int, context: Context): String { override fun labelForValue(value: Int, context: Context): String {
val suffix = when (value%10) { val suffix = when (value % 10) {
1 -> context.getString(R.string.ordinal_suffix_first) 1 -> context.getString(R.string.ordinal_suffix_first)
2 -> context.getString(R.string.ordinal_suffix_second) 2 -> context.getString(R.string.ordinal_suffix_second)
3 -> context.getString(R.string.ordinal_suffix_third) 3 -> context.getString(R.string.ordinal_suffix_third)
else -> context.getString(R.string.ordinal_suffix_default) else -> context.getString(R.string.ordinal_suffix_default)
} }
return "$value$suffix "+context.getString(R.string.position) return "$value$suffix " + context.getString(R.string.position)
} }
override fun entityName(context: Context): String { override fun entityName(context: Context): String {
@ -498,14 +516,18 @@ sealed class QueryCondition : RowRepresentable {
} }
} }
open class NetAmount : ListOfDouble() open class NetAmount : ListOfDouble() {
override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return DoubleValueListFilterItemRow(this, filterSectionRow)
}
}
class NetAmountWon : NetAmount() class NetAmountWon : NetAmount()
class NetAmountLost : NetAmount() { class NetAmountLost : NetAmount() {
override var sign: Int = -1 override var sign: Int = -1
} }
class TournamentNumberOfPlayer : ListOfInt() { class TournamentNumberOfPlayer : UserInputListOfInt() {
override fun labelForValue(value: Int, context: Context): String { override fun labelForValue(value: Int, context: Context): String {
return value.toString() + " " + context.getString(R.string.number_of_players) return value.toString() + " " + context.getString(R.string.number_of_players)
} }
@ -547,7 +569,7 @@ sealed class QueryCondition : RowRepresentable {
} }
} }
class AnyYear() : ListOfInt() { class AnyYear() : UserInputListOfInt() {
override fun labelForValue(value: Int, context: Context): String { override fun labelForValue(value: Int, context: Context): String {
return "$value" return "$value"
} }
@ -580,14 +602,14 @@ sealed class QueryCondition : RowRepresentable {
return value.toString() return value.toString()
} }
override fun entityName(context: Context): String { // override fun entityName(context: Context): String {
return this.resId?.let { // return this.resId?.let {
" " + context.getString(it) // " " + context.getString(it)
} ?: "" // } ?: ""
} // }
} }
class Duration(value: Int) : SingleInt(value) { class Duration(value: Int) : UserInputSingleInt(value) {
override var operator = Operator.EQUALS override var operator = Operator.EQUALS
var minutes: Int var minutes: Int
@ -617,20 +639,10 @@ sealed class QueryCondition : RowRepresentable {
class StartedFromTime(date: Date) : TimeQuery(date) { class StartedFromTime(date: Date) : TimeQuery(date) {
override var operator = Operator.MORE override var operator = Operator.MORE
// constructor(date: Date) : this() {
// singleValue = date
// }
} }
class EndedToTime(date: Date) : TimeQuery(date) { class EndedToTime(date: Date) : TimeQuery(date) {
override var operator = Operator.LESS override var operator = Operator.LESS
// constructor(date: Date) : this() {
// singleValue = date
// }
} }
interface CustomFieldRelated { interface CustomFieldRelated {
@ -717,7 +729,7 @@ sealed class QueryCondition : RowRepresentable {
} }
open fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow { open fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return BaseFilterItemRow(this, filterSectionRow) return FixedValueFilterItemRow(this, filterSectionRow)
} }
/** /**

@ -167,9 +167,7 @@ class StatisticsFragment : FilterableFragment(), RealmAsyncListener {
*/ */
private fun createSessionGroupsAndStartCompute(realm: Realm): Report { private fun createSessionGroupsAndStartCompute(realm: Realm): Report {
val filter: Filter? = this.currentFilter(this.requireContext(), realm)?.let { val filter: Filter? = null
if (it.filterableType == currentFilterable) { it } else { null }
}
val allStats: List<Stat> = listOf( val allStats: List<Stat> = listOf(
Stat.NET_RESULT, Stat.NET_RESULT,

@ -114,7 +114,7 @@ open class FilterDetailsFragment : RealmFragment(), RowRepresentableDelegate {
return return
} }
(row as? BaseFilterItemRow)?.let { (row as? FixedValueFilterItemRow)?.let {
when (val condition = it.rawCondition) { when (val condition = it.rawCondition) {
is QueryCondition.DateQuery -> DateTimePickerManager.create( is QueryCondition.DateQuery -> DateTimePickerManager.create(
requireContext(), requireContext(),
@ -130,8 +130,8 @@ open class FilterDetailsFragment : RealmFragment(), RowRepresentableDelegate {
val data = row.editingDescriptors(mapOf("hours" to hours, "minutes" to minutes)) val data = row.editingDescriptors(mapOf("hours" to hours, "minutes" to minutes))
showBottomSheet(row, this, data, true) showBottomSheet(row, this, data, true)
} }
is QueryCondition.ListOfValues<*> -> { is QueryCondition.SingleValue<*>, is QueryCondition.ListOfValues<*> -> {
val valueAsString: String? = (row as FilterValueHolder).singleValue?.toString() val valueAsString = (row as FilterItemRow).singleValue?.toString()
// row.list.firstOrNull()?.let { // row.list.firstOrNull()?.let {
// valueAsString = row.list.firstOrNull()?.toString() // valueAsString = row.list.firstOrNull()?.toString()
// } // }

@ -10,7 +10,6 @@ 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.FilterCategoryRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterItemRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterItemRow
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterValueHolder
import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.NULL_TEXT
class FilterDetailsViewModelFactory(var filter: Filter, var categoryRow: FilterCategoryRow): ViewModelProvider.Factory { class FilterDetailsViewModelFactory(var filter: Filter, var categoryRow: FilterCategoryRow): ViewModelProvider.Factory {
@ -41,7 +40,7 @@ class FilterDetailsViewModel(categoryRow: FilterCategoryRow, var filter: Filter)
override fun charSequenceForRow(row: RowRepresentable, context: Context): CharSequence { override fun charSequenceForRow(row: RowRepresentable, context: Context): CharSequence {
return when (row) { return when (row) {
is FilterValueHolder -> { is FilterItemRow -> {
row.valueFormatted(context) row.valueFormatted(context)
} }
else -> super.charSequenceForRow(row, context, 0) else -> super.charSequenceForRow(row, context, 0)

@ -3,6 +3,7 @@ package net.pokeranalytics.android.ui.view.rowrepresentable
import android.content.Context import android.content.Context
import android.text.InputType import android.text.InputType
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.realm.FilterCondition import net.pokeranalytics.android.model.realm.FilterCondition
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType
@ -19,6 +20,16 @@ interface FilterItemRow : RowRepresentable {
fun updateValue(fc: FilterCondition) { } fun updateValue(fc: FilterCondition) { }
/***
* The formatted value at the right of the table cell
*/
fun valueFormatted(context: Context): CharSequence?
/***
* The value at the right of the table cell
*/
val singleValue: Any?
val sectionToExclude: List<FilterSectionRow>? val sectionToExclude: List<FilterSectionRow>?
get() { get() {
val excluded = arrayListOf<FilterSectionRow>() val excluded = arrayListOf<FilterSectionRow>()
@ -34,19 +45,7 @@ interface FilterItemRow : RowRepresentable {
} }
return null return null
} }
}
interface FilterValueHolder {
fun valueFormatted(context: Context): CharSequence?
val singleValue: Any?
}
open class BaseFilterItemRow(queryCondition: QueryCondition, override var filterSectionRow: FilterSectionRow) : FilterItemRow {
override val rawCondition: QueryCondition = queryCondition
override val queryCondition: QueryCondition?
get() { return rawCondition }
// Row Representable // Row Representable
@ -73,7 +72,7 @@ open class BaseFilterItemRow(queryCondition: QueryCondition, override var filter
RowRepresentableEditDescriptor(minutes, R.string.minute, inputType = InputType.TYPE_CLASS_NUMBER) RowRepresentableEditDescriptor(minutes, R.string.minute, inputType = InputType.TYPE_CLASS_NUMBER)
) )
} }
is QueryCondition.ListOfValues<*> -> { is QueryCondition.SingleValue<*>, is QueryCondition.ListOfValues<*> -> {
val valueAsString: String? by map val valueAsString: String? by map
val hint = when (this.queryCondition?.operator) { val hint = when (this.queryCondition?.operator) {
QueryCondition.Operator.MORE, QueryCondition.Operator.LESS -> { QueryCondition.Operator.MORE, QueryCondition.Operator.LESS -> {
@ -96,8 +95,24 @@ open class BaseFilterItemRow(queryCondition: QueryCondition, override var filter
} }
open class FixedValueFilterItemRow(queryCondition: QueryCondition,
override var filterSectionRow: FilterSectionRow) : FilterItemRow {
abstract class ValueFilterItemRow<T: Comparable<T>>(queryCondition: QueryCondition.SingleValue<T>, filterSectionRow: FilterSectionRow): BaseFilterItemRow(queryCondition, filterSectionRow), FilterValueHolder { override val rawCondition: QueryCondition = queryCondition
override val queryCondition: QueryCondition?
get() { return rawCondition }
override fun valueFormatted(context: Context): CharSequence? {
throw PAIllegalStateException("Not applicable")
}
override val singleValue: Any?
get() { throw PAIllegalStateException("Not applicable") }
}
abstract class ValueFilterItemRow<T: Comparable<T>>(queryCondition: QueryCondition.SingleValue<T>, filterSectionRow: FilterSectionRow): FixedValueFilterItemRow(queryCondition, filterSectionRow) {
private var valueCondition: QueryCondition.SingleValue<T> = queryCondition private var valueCondition: QueryCondition.SingleValue<T> = queryCondition
@ -113,8 +128,9 @@ abstract class ValueFilterItemRow<T: Comparable<T>>(queryCondition: QueryConditi
} }
override fun valueFormatted(context: Context): CharSequence? { override fun valueFormatted(context: Context): CharSequence? {
this.value?.let {
return this.valueCondition.labelForValue(it, context) (this.queryCondition as? QueryCondition.SingleValue<T>)?.let {
return it.labelForValue(it.singleValue, context)
} }
return NULL_TEXT return NULL_TEXT
} }
@ -132,7 +148,7 @@ abstract class ValueFilterItemRow<T: Comparable<T>>(queryCondition: QueryConditi
} }
abstract class ValueListFilterItemRow<T: Comparable<T>>(queryCondition: QueryCondition.ListOfValues<T>, filterSectionRow: FilterSectionRow) abstract class ValueListFilterItemRow<T: Comparable<T>>(queryCondition: QueryCondition.ListOfValues<T>, filterSectionRow: FilterSectionRow)
: BaseFilterItemRow(queryCondition, filterSectionRow), FilterValueHolder { : FixedValueFilterItemRow(queryCondition, filterSectionRow) {
private var listCondition: QueryCondition.ListOfValues<T> = queryCondition private var listCondition: QueryCondition.ListOfValues<T> = queryCondition
@ -154,8 +170,9 @@ abstract class ValueListFilterItemRow<T: Comparable<T>>(queryCondition: QueryCon
} }
override fun valueFormatted(context: Context): CharSequence? { override fun valueFormatted(context: Context): CharSequence? {
this.list.firstOrNull()?.let {
return this.listCondition.labelForValue(it, context) (this.queryCondition as? QueryCondition.ListOfValues<T>)?.let {
return it.labelForValue(this.list.first(), context)
} }
return NULL_TEXT return NULL_TEXT
} }
@ -165,14 +182,11 @@ abstract class ValueListFilterItemRow<T: Comparable<T>>(queryCondition: QueryCon
return this.list.firstOrNull() return this.list.firstOrNull()
} }
// override fun getDisplayName(context: Context): String {
// return this.listCondition.getDisplayName(context, this.list)
// }
override fun updateValue(fc: FilterCondition) { override fun updateValue(fc: FilterCondition) {
val queryCondition = fc.queryCondition as QueryCondition.ListOfValues<T> val queryCondition = fc.queryCondition as QueryCondition.ListOfValues<T>
this.list = queryCondition.listOfValues this.list = queryCondition.listOfValues
} }
} }
class DateFilterItemRow(queryCondition: QueryCondition.SingleDate, filterSectionRow: FilterSectionRow): ValueFilterItemRow<Date>(queryCondition, filterSectionRow) class DateFilterItemRow(queryCondition: QueryCondition.SingleDate, filterSectionRow: FilterSectionRow): ValueFilterItemRow<Date>(queryCondition, filterSectionRow)
@ -181,7 +195,3 @@ class IntFilterItemRow(queryCondition: QueryCondition.SingleInt, filterSectionRo
class IntValueListFilterItemRow(queryCondition: QueryCondition.ListOfInt, filterSectionRow: FilterSectionRow): ValueListFilterItemRow<Int>(queryCondition, filterSectionRow) class IntValueListFilterItemRow(queryCondition: QueryCondition.ListOfInt, filterSectionRow: FilterSectionRow): ValueListFilterItemRow<Int>(queryCondition, filterSectionRow)
class DoubleValueListFilterItemRow(queryCondition: QueryCondition.ListOfDouble, filterSectionRow: FilterSectionRow): ValueListFilterItemRow<Double>(queryCondition, filterSectionRow) class DoubleValueListFilterItemRow(queryCondition: QueryCondition.ListOfDouble, filterSectionRow: FilterSectionRow): ValueListFilterItemRow<Double>(queryCondition, filterSectionRow)
class StringValueListFilterItemRow(queryCondition: QueryCondition.ListOfString, filterSectionRow: FilterSectionRow): ValueListFilterItemRow<String>(queryCondition, filterSectionRow) class StringValueListFilterItemRow(queryCondition: QueryCondition.ListOfString, filterSectionRow: FilterSectionRow): ValueListFilterItemRow<String>(queryCondition, filterSectionRow)
//interface FilterElementRow : RowRepresentable {
//
//}
Loading…
Cancel
Save