Merge branch 'filterfix'

kmm
Laurent 5 years ago
commit 6c2367aa7f
  1. 18
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/BlindFilterInstrumentedTest.kt
  2. 37
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/DateFilterInstrumentedUnitTest.kt
  3. 6
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/RealmFilterInstrumentedUnitTest.kt
  4. 64
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt
  5. 8
      app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt
  6. 18
      app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt
  7. 16
      app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt
  8. 360
      app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt
  9. 32
      app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt
  10. 24
      app/src/main/java/net/pokeranalytics/android/model/realm/FilterCondition.kt
  11. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt
  12. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/BaseFragment.kt
  13. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetEditTextFragment.kt
  14. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt
  15. 4
      app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarDetailsActivity.kt
  16. 235
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterDetailsFragment.kt
  17. 96
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterDetailsViewModel.kt
  18. 5
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterHandler.kt
  19. 10
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterViewModel.kt
  20. 12
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersActivity.kt
  21. 25
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersFragment.kt
  22. 11
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersListActivity.kt
  23. 8
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt
  24. 61
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt
  25. 197
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterItemRow.kt
  26. 182
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt
  27. 76
      app/src/main/res/layout/fragment_filter_details.xml
  28. 27
      app/src/test/java/net/pokeranalytics/android/InstantiationTest.kt

@ -47,9 +47,9 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() {
listOfValues = arrayListOf(s1.blinds!!) listOfValues = arrayListOf(s1.blinds!!)
} }
blind.filterSectionRow = FilterSectionRow.Blind // blind.filterSectionRow = FilterSectionRow.Blind
val filterElement = FilterCondition(filterElementRows = arrayListOf(blind)) val filterElement = FilterCondition(arrayListOf(blind), FilterSectionRow.Blind)
filter.updateValueBy(filterElement) filter.updateValueBy(filterElement)
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -97,10 +97,7 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() {
listOfValues = arrayListOf(s2.blinds!!) listOfValues = arrayListOf(s2.blinds!!)
} }
blind1.filterSectionRow = FilterSectionRow.Blind val filterElements = FilterCondition(arrayListOf(blind1, blind2), FilterSectionRow.Blind)
blind2.filterSectionRow = FilterSectionRow.Blind
val filterElements = FilterCondition(filterElementRows = arrayListOf(blind1, blind2))
filter.updateValueBy(filterElements) filter.updateValueBy(filterElements)
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -146,9 +143,7 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() {
listOfValues = arrayListOf(s3.blinds!!) listOfValues = arrayListOf(s3.blinds!!)
} }
blind.filterSectionRow = FilterSectionRow.Blind val filterElement = FilterCondition(arrayListOf(blind), FilterSectionRow.Blind)
val filterElement = FilterCondition(filterElementRows = arrayListOf(blind))
filter.updateValueBy(filterElement) filter.updateValueBy(filterElement)
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -196,10 +191,7 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() {
listOfValues = arrayListOf(s2.blinds!!) listOfValues = arrayListOf(s2.blinds!!)
} }
blind1.filterSectionRow = FilterSectionRow.Blind val filterElement = FilterCondition(arrayListOf(blind1, blind2), FilterSectionRow.Blind)
blind2.filterSectionRow = FilterSectionRow.Blind
val filterElement = FilterCondition(filterElementRows = arrayListOf(blind1, blind2))
filter.updateValueBy(filterElement) filter.updateValueBy(filterElement)
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))

@ -35,8 +35,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
cal.time = s1.startDate cal.time = s1.startDate
val filterElementRow = QueryCondition.AnyDayOfWeek().apply { listOfValues = arrayListOf(cal.get(Calendar.DAY_OF_WEEK)) } val filterElementRow = QueryCondition.AnyDayOfWeek().apply { listOfValues = arrayListOf(cal.get(Calendar.DAY_OF_WEEK)) }
filterElementRow.filterSectionRow = FilterSectionRow.DynamicDate val filterElement = FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.DynamicDate)
val filterElement = FilterCondition(arrayListOf(filterElementRow))
filter.updateValueBy(filterElement) filter.updateValueBy(filterElement)
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -64,8 +63,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
cal.time = s1.startDate cal.time = s1.startDate
val filterElementRow = QueryCondition.AnyMonthOfYear().apply { listOfValues = arrayListOf(cal.get(Calendar.MONTH)) } val filterElementRow = QueryCondition.AnyMonthOfYear().apply { listOfValues = arrayListOf(cal.get(Calendar.MONTH)) }
filterElementRow.filterSectionRow = FilterSectionRow.DynamicDate val filterElement = FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.DynamicDate)
val filterElement = FilterCondition(arrayListOf(filterElementRow))
filter.updateValueBy(filterElement) filter.updateValueBy(filterElement)
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -92,8 +90,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.AnyYear() val filter = QueryCondition.AnyYear()
cal.time = s1.startDate cal.time = s1.startDate
val filterElementRow = QueryCondition.AnyYear().apply { listOfValues = arrayListOf(cal.get(Calendar.YEAR)) } val filterElementRow = QueryCondition.AnyYear().apply { listOfValues = arrayListOf(cal.get(Calendar.YEAR)) }
filterElementRow.filterSectionRow = FilterSectionRow.DynamicDate val filterElement = FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.DynamicDate)
val filterElement = FilterCondition(arrayListOf(filterElementRow))
filter.updateValueBy(filterElement) filter.updateValueBy(filterElement)
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -384,10 +381,9 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val s2 = Session.testInstance(100.0, true, cal.time, 1) val s2 = Session.testInstance(100.0, true, cal.time, 1)
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.StartedFromDate() val filter = QueryCondition.StartedFromDate(Date())
val filterElementRow = QueryCondition.StartedFromDate().apply { singleValue = s2.startDate!!} val filterElementRow = QueryCondition.StartedFromDate(Date()).apply { singleValue = s2.startDate!!}
filterElementRow.filterSectionRow = FilterSectionRow.FixedDate filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.FixedDate))
filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -412,10 +408,9 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.StartedToDate() val filter = QueryCondition.StartedToDate(Date())
val filterElementRow = QueryCondition.StartedToDate().apply { singleValue = s1.startDate!! } val filterElementRow = QueryCondition.StartedToDate(Date()).apply { singleValue = s1.startDate!! }
filterElementRow.filterSectionRow = FilterSectionRow.FixedDate filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.FixedDate))
filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -441,10 +436,9 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.EndedFromDate() val filter = QueryCondition.EndedFromDate(Date())
val filterElementRow = QueryCondition.EndedFromDate().apply { singleValue = s2.endDate() } val filterElementRow = QueryCondition.EndedFromDate(Date()).apply { singleValue = s2.endDate() }
filterElementRow.filterSectionRow = FilterSectionRow.FixedDate filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.FixedDate))
filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -470,10 +464,9 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filter = QueryCondition.EndedToDate() val filter = QueryCondition.EndedToDate(Date())
val filterElementRow = QueryCondition.EndedToDate().apply { singleValue = s1.endDate() } val filterElementRow = QueryCondition.EndedToDate(Date()).apply { singleValue = s1.endDate() }
filterElementRow.filterSectionRow = FilterSectionRow.FixedDate filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.FixedDate))
filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))

@ -5,6 +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.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
@ -24,8 +25,9 @@ class RealmFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
filter.name = "testSaveLoadCashFilter" filter.name = "testSaveLoadCashFilter"
val filterElement = QueryCondition.IsCash val filterElement = QueryCondition.IsCash
filterElement.filterSectionRow = FilterSectionRow.CashOrTournament val filterItemRow = FixedValueFilterItemRow(filterElement, FilterSectionRow.CashOrTournament)
filter.createOrUpdateFilterConditions(arrayListOf(filterElement))
filter.createOrUpdateFilterConditions(arrayListOf(filterItemRow))
val useCount = filter.countBy(FilterCategoryRow.GENERAL) val useCount = filter.countBy(FilterCategoryRow.GENERAL)
Assert.assertEquals(1, useCount) Assert.assertEquals(1, useCount)

@ -110,8 +110,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.AnyBankroll() val filter = QueryCondition.AnyBankroll()
val filterElementRow = QueryCondition.AnyBankroll().apply { setObject(b1) } val filterElementRow = QueryCondition.AnyBankroll().apply { setObject(b1) }
filterElementRow.filterSectionRow = FilterSectionRow.Bankroll filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.Bankroll))
filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -141,11 +140,9 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.AnyBankroll() val filter = QueryCondition.AnyBankroll()
val filterElementRow = QueryCondition.AnyBankroll().apply { setObject(b1) } val filterElementRow = QueryCondition.AnyBankroll().apply { setObject(b1) }
filterElementRow.filterSectionRow = FilterSectionRow.Bankroll
val filterElementRow2 = QueryCondition.AnyBankroll().apply { setObject(b2) } val filterElementRow2 = QueryCondition.AnyBankroll().apply { setObject(b2) }
filterElementRow2.filterSectionRow = FilterSectionRow.Bankroll
filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2))) filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow, filterElementRow2), FilterSectionRow.Bankroll))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -169,7 +166,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val anyGame = QueryCondition.AnyGame(g2) val anyGame = QueryCondition.AnyGame(g2)
val fc = FilterCondition(filterElementRows = arrayListOf(anyGame)) val fc = FilterCondition(arrayListOf(anyGame), FilterSectionRow.Game)
val sessions = Filter.queryOn<Session>(realm, Query(fc.queryCondition)) val sessions = Filter.queryOn<Session>(realm, Query(fc.queryCondition))
Assert.assertEquals(1, sessions.size) Assert.assertEquals(1, sessions.size)
@ -197,10 +194,10 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val filterElementRow = QueryCondition.AnyGame().apply { setObject(g2) } val filterElementRow = QueryCondition.AnyGame().apply { setObject(g2) }
filterElementRow.filterSectionRow = FilterSectionRow.Game
val filterElementRow2 = QueryCondition.AnyGame().apply { setObject(g3) } val filterElementRow2 = QueryCondition.AnyGame().apply { setObject(g3) }
filterElementRow2.filterSectionRow = FilterSectionRow.Game
val filterCondition = FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2)) val filterCondition = FilterCondition(arrayListOf(filterElementRow, filterElementRow2), FilterSectionRow.Game)
val queryCondition = filterCondition.queryCondition val queryCondition = filterCondition.queryCondition
val sessions = Filter.queryOn<Session>(realm, Query(queryCondition)) val sessions = Filter.queryOn<Session>(realm, Query(queryCondition))
@ -225,8 +222,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.AnyLocation() val filter = QueryCondition.AnyLocation()
val filterElementRow = QueryCondition.AnyLocation().apply { setObject(l1) } val filterElementRow = QueryCondition.AnyLocation().apply { setObject(l1) }
filterElementRow.filterSectionRow = FilterSectionRow.Location filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.Location))
filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -257,11 +253,9 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.AnyLocation() val filter = QueryCondition.AnyLocation()
val filterElementRow = QueryCondition.AnyLocation().apply { setObject(l1) } val filterElementRow = QueryCondition.AnyLocation().apply { setObject(l1) }
filterElementRow.filterSectionRow = FilterSectionRow.Location
val filterElementRow2 = QueryCondition.AnyLocation().apply { setObject(l3) } val filterElementRow2 = QueryCondition.AnyLocation().apply { setObject(l3) }
filterElementRow2.filterSectionRow = FilterSectionRow.Location
filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2))) filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow, filterElementRow2), FilterSectionRow.Location))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -287,8 +281,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.AnyTournamentName() val filter = QueryCondition.AnyTournamentName()
val filterElementRow = QueryCondition.AnyTournamentName().apply { setObject(t1) } val filterElementRow = QueryCondition.AnyTournamentName().apply { setObject(t1) }
filterElementRow.filterSectionRow = FilterSectionRow.TournamentName filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.TournamentName))
filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -318,10 +311,8 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.AnyTournamentName() val filter = QueryCondition.AnyTournamentName()
val filterElementRow = QueryCondition.AnyTournamentName().apply { setObject(t1) } val filterElementRow = QueryCondition.AnyTournamentName().apply { setObject(t1) }
filterElementRow.filterSectionRow = FilterSectionRow.TournamentName
val filterElementRow2 = QueryCondition.AnyTournamentName().apply { setObject(t2) } val filterElementRow2 = QueryCondition.AnyTournamentName().apply { setObject(t2) }
filterElementRow.filterSectionRow = FilterSectionRow.TournamentName filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow, filterElementRow2), FilterSectionRow.TournamentName))
filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2)))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -354,12 +345,10 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.AllTournamentFeature() val filter = QueryCondition.AllTournamentFeature()
val filterElementRow = QueryCondition.AllTournamentFeature().apply { setObject(t1) } val filterElementRow = QueryCondition.AllTournamentFeature().apply { setObject(t1) }
filterElementRow.filterSectionRow = FilterSectionRow.TournamentFeature
val filterElementRow2 = QueryCondition.AllTournamentFeature().apply { setObject(t2) } val filterElementRow2 = QueryCondition.AllTournamentFeature().apply { setObject(t2) }
filterElementRow2.filterSectionRow = FilterSectionRow.TournamentFeature
val filterElementRow3 = QueryCondition.AllTournamentFeature().apply { setObject(t4) } val filterElementRow3 = QueryCondition.AllTournamentFeature().apply { setObject(t4) }
filterElementRow3.filterSectionRow = FilterSectionRow.TournamentFeature
filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2, filterElementRow3))) filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow, filterElementRow2, filterElementRow3), FilterSectionRow.TournamentFeature))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -389,14 +378,11 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.AnyTournamentFeature() val filter = QueryCondition.AnyTournamentFeature()
val filterElementRow = QueryCondition.AnyTournamentFeature().apply { setObject(t1) } val filterElementRow = QueryCondition.AnyTournamentFeature().apply { setObject(t1) }
filterElementRow.filterSectionRow = FilterSectionRow.TournamentFeature
val filterElementRow2 = QueryCondition.AnyTournamentFeature().apply { setObject(t2) } val filterElementRow2 = QueryCondition.AnyTournamentFeature().apply { setObject(t2) }
filterElementRow2.filterSectionRow = FilterSectionRow.TournamentFeature
val filterElementRow3 = QueryCondition.AnyTournamentFeature().apply { setObject(t3) } val filterElementRow3 = QueryCondition.AnyTournamentFeature().apply { setObject(t3) }
filterElementRow3.filterSectionRow = FilterSectionRow.TournamentFeature
val filterElementRow4 = QueryCondition.AnyTournamentFeature().apply { setObject(t4) } val filterElementRow4 = QueryCondition.AnyTournamentFeature().apply { setObject(t4) }
filterElementRow4.filterSectionRow = FilterSectionRow.TournamentFeature
filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2, filterElementRow3, filterElementRow4))) filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow, filterElementRow2, filterElementRow3, filterElementRow4), FilterSectionRow.TournamentFeature))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -423,8 +409,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.AnyTournamentFeature() val filter = QueryCondition.AnyTournamentFeature()
val filterElementRow = QueryCondition.AnyTournamentFeature().apply { setObject(t2) } val filterElementRow = QueryCondition.AnyTournamentFeature().apply { setObject(t2) }
filterElementRow.filterSectionRow = FilterSectionRow.TournamentFeature filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.TournamentFeature))
filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -448,10 +433,9 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.AnyTableSize() val filter = QueryCondition.AnyTableSize()
val filterElementRow = QueryCondition.AnyTableSize().apply { listOfValues = arrayListOf(2) } val filterElementRow = QueryCondition.AnyTableSize().apply { listOfValues = arrayListOf(2) }
filterElementRow.filterSectionRow = FilterSectionRow.TableSize
val filterElementRow2 = QueryCondition.AnyTableSize().apply { listOfValues = arrayListOf(4) } val filterElementRow2 = QueryCondition.AnyTableSize().apply { listOfValues = arrayListOf(4) }
filterElementRow.filterSectionRow = FilterSectionRow.TableSize
filter.updateValueBy(FilterCondition(filterElementRows = arrayListOf(filterElementRow, filterElementRow2))) filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow, filterElementRow2), FilterSectionRow.TableSize))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -475,8 +459,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.NetAmountWon() val filter = QueryCondition.NetAmountWon()
val filterElementRow = QueryCondition.more<QueryCondition.NetAmountWon>().apply { listOfValues = arrayListOf(204.0) } val filterElementRow = QueryCondition.more<QueryCondition.NetAmountWon>().apply { listOfValues = arrayListOf(204.0) }
filterElementRow.filterSectionRow = FilterSectionRow.Value filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.Value))
filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, Query(filterElementRow)) val sessions = Filter.queryOn<Session>(realm, Query(filterElementRow))
@ -500,8 +483,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filter = QueryCondition.NetAmountWon() val filter = QueryCondition.NetAmountWon()
val filterElementRow = QueryCondition.less<QueryCondition.NetAmountWon>().apply { listOfValues = arrayListOf(540.0) } val filterElementRow = QueryCondition.less<QueryCondition.NetAmountWon>().apply { listOfValues = arrayListOf(540.0) }
filterElementRow.filterSectionRow = FilterSectionRow.Value filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.Value))
filter.updateValueBy(FilterCondition(arrayListOf(filterElementRow)))
val sessions = Filter.queryOn<Session>(realm, Query(filter)) val sessions = Filter.queryOn<Session>(realm, Query(filter))
@ -525,13 +507,11 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {
val filterMore = QueryCondition.NetAmountWon() val filterMore = QueryCondition.NetAmountWon()
val filterElementRow = QueryCondition.more<QueryCondition.NetAmountWon>().apply { listOfValues = arrayListOf(199.0) } val filterElementRow = QueryCondition.more<QueryCondition.NetAmountWon>().apply { listOfValues = arrayListOf(199.0) }
filterElementRow.filterSectionRow = FilterSectionRow.Value filterMore.updateValueBy(FilterCondition(arrayListOf(filterElementRow), FilterSectionRow.Value))
filterMore.updateValueBy(FilterCondition(arrayListOf(filterElementRow)))
val filterLess = QueryCondition.NetAmountWon() val filterLess = QueryCondition.NetAmountWon()
val filterElementRow2 = QueryCondition.less<QueryCondition.NetAmountWon>().apply { listOfValues = arrayListOf(400.0) } val filterElementRow2 = QueryCondition.less<QueryCondition.NetAmountWon>().apply { listOfValues = arrayListOf(400.0) }
filterElementRow2.filterSectionRow = FilterSectionRow.Value filterLess.updateValueBy(FilterCondition(arrayListOf(filterElementRow2), FilterSectionRow.Value))
filterLess.updateValueBy(FilterCondition(arrayListOf(filterElementRow2)))
val sessions = Filter.queryOn<Session>(realm, Query(filterMore, filterLess)) val sessions = Filter.queryOn<Session>(realm, Query(filterMore, filterLess))

@ -220,14 +220,10 @@ class BankrollReportSetup(val bankrollId: String? = null, val from: Date? = null
query.add(bankrollCondition) query.add(bankrollCondition)
} }
this.from?.let { this.from?.let {
val fromCondition = QueryCondition.StartedFromDate() query.add(QueryCondition.StartedFromDate(it))
fromCondition.singleValue = it
query.add(fromCondition)
} }
this.to?.let { this.to?.let {
val toCondition = QueryCondition.StartedToDate() query.add(QueryCondition.StartedToDate(it))
toCondition.singleValue = it
query.add(toCondition)
} }
return query return query
} }

@ -1,7 +1,5 @@
package net.pokeranalytics.android.exceptions package net.pokeranalytics.android.exceptions
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow
class ModelException(message: String) : Exception(message) class ModelException(message: String) : Exception(message)
class FormattingException(message: String) : Exception(message) class FormattingException(message: String) : Exception(message)
class RowRepresentableEditDescriptorException(message: String) : Exception(message) class RowRepresentableEditDescriptorException(message: String) : Exception(message)
@ -14,16 +12,16 @@ class PAIllegalStateException(message: String) : Exception(message)
sealed class PokerAnalyticsException(message: String) : Exception(message) { sealed class PokerAnalyticsException(message: String) : Exception(message) {
object FilterElementUnknownName : PokerAnalyticsException(message = "No filterElement name was found to identify the queryCondition") object FilterElementUnknownName : PokerAnalyticsException(message = "No filterElement name was found to identify the queryCondition")
object FilterElementUnknownSectionName: PokerAnalyticsException(message = "No filterElement section name was found to identify the queryCondition") // object FilterElementUnknownSectionName: PokerAnalyticsException(message = "No filterElement section name was found to identify the queryCondition")
object FilterMissingEntity: PokerAnalyticsException(message = "This queryWith has no entity initialized") // object FilterMissingEntity: PokerAnalyticsException(message = "This queryWith has no entity initialized")
object FilterUnhandledEntity : PokerAnalyticsException(message = "This entity is not filterable") // object FilterUnhandledEntity : PokerAnalyticsException(message = "This entity is not filterable")
object QueryValueMapUnknown: PokerAnalyticsException(message = "fieldName is missing") object QueryValueMapUnknown: PokerAnalyticsException(message = "fieldName is missing")
object QueryTypeUnhandled: PokerAnalyticsException(message = "queryWith type not handled") object QueryTypeUnhandled: PokerAnalyticsException(message = "queryWith type not handled")
object QueryValueMapUnexpectedValue: PokerAnalyticsException(message = "valueMap null not expected") object QueryValueMapUnexpectedValue: PokerAnalyticsException(message = "valueMap null not expected")
object FilterElementExpectedValueMissing : PokerAnalyticsException(message = "queryWith is empty or null") object FilterElementExpectedValueMissing : PokerAnalyticsException(message = "queryWith is empty or null")
data class FilterElementTypeMissing(val filterElementRow: FilterElementRow) : PokerAnalyticsException(message = "queryWith element '$filterElementRow' type is missing") // data class FilterElementTypeMissing(val filterElementRow: FilterElementRow) : PokerAnalyticsException(message = "queryWith element '$filterElementRow' type is missing")
data class QueryValueMapMissingKeys(val missingKeys: List<String>) : PokerAnalyticsException(message = "valueMap does not contain $missingKeys") // data class QueryValueMapMissingKeys(val missingKeys: List<String>) : PokerAnalyticsException(message = "valueMap does not contain $missingKeys")
data class UnknownQueryTypeForRow(val filterElementRow: FilterElementRow) : PokerAnalyticsException(message = "no queryWith type for $filterElementRow") // data class UnknownQueryTypeForRow(val filterElementRow: FilterElementRow) : PokerAnalyticsException(message = "no queryWith type for $filterElementRow")
data class MissingFieldNameForQueryCondition(val name: String) : PokerAnalyticsException(message = "Missing fieldname for QueryCondition ${name}") // data class MissingFieldNameForQueryCondition(val name: String) : PokerAnalyticsException(message = "Missing fieldname for QueryCondition ${name}")
object InputFragmentException : PokerAnalyticsException(message = "RowEditableDelegate must be a Fragment") // object InputFragmentException : PokerAnalyticsException(message = "RowEditableDelegate must be a Fragment")
} }

@ -84,14 +84,14 @@ class Query {
} }
// println("<<<<<< ${realmQuery.description}") // println("<<<<<< ${realmQuery.description}")
val queryLast = this.conditions.firstOrNull { // val queryLast = this.conditions.firstOrNull {
it is QueryCondition.Last // it is QueryCondition.Last
} // }
queryLast?.let {qc -> // queryLast?.let {qc ->
(qc as QueryCondition.Last).singleValue?.let { // (qc as QueryCondition.Last).singleValue?.let {
return realmQuery.limit(it.toLong()) // return realmQuery.limit(it.toLong())
} // }
} // }
return realmQuery return realmQuery
} }

@ -16,31 +16,50 @@ import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow import net.pokeranalytics.android.ui.view.rowrepresentable.*
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow
import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.UserDefaults import net.pokeranalytics.android.util.UserDefaults
import net.pokeranalytics.android.util.extensions.* import net.pokeranalytics.android.util.extensions.*
import java.text.DateFormatSymbols import java.text.DateFormatSymbols
import java.text.NumberFormat import java.text.NumberFormat
import java.util.* import java.util.*
import kotlin.collections.ArrayList 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 : FilterElementRow {
companion object { companion object {
fun <T: Any> newInstance(kClass: KClass<T>): T {
return try {
kClass.objectInstance ?: kClass.java.newInstance()
} catch (e: Exception) {
// some object instance can fail due to: java.lang.Class has no zero argument constructor
// We should have just one constructor with a single parameter
val primaryConstructor = kClass.java.declaredConstructors.first()
val paramClass = primaryConstructor.parameterTypes.first()
val param = when (paramClass) {
Int::class.java -> 0
Double::class.java -> 0.0
else -> paramClass.newInstance()
}
val constructor = kClass.java.getDeclaredConstructor(paramClass)
constructor.newInstance(param)
}
}
inline fun <reified T : QueryCondition> more(): T { inline fun <reified T : QueryCondition> more(): T {
return T::class.java.newInstance().apply { this.operator = Operator.MORE } return newInstance(T::class).apply { this.operator = Operator.MORE }
} }
inline fun <reified T : QueryCondition> less(): T { inline fun <reified T : QueryCondition> less(): T {
return T::class.java.newInstance().apply { this.operator = Operator.LESS } return newInstance(T::class).apply { this.operator = Operator.LESS }
} }
inline fun <reified T : QueryCondition> moreOrLess(): ArrayList<T> { inline fun <reified T : QueryCondition> moreOrLess(): ArrayList<T> {
@ -49,8 +68,7 @@ sealed class QueryCondition : FilterElementRow {
fun <T : QueryCondition> valueOf(name: String): T { fun <T : QueryCondition> valueOf(name: String): T {
val kClass = Class.forName("${QueryCondition::class.qualifiedName}$$name").kotlin val kClass = Class.forName("${QueryCondition::class.qualifiedName}$$name").kotlin
val instance = kClass.objectInstance ?: kClass.java.newInstance() return newInstance(kClass) as T
return instance as T
} }
inline fun <reified T : Identifiable> getInstance(): QueryCondition { inline fun <reified T : Identifiable> getInstance(): QueryCondition {
@ -125,25 +143,29 @@ 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: MutableList<T>
abstract fun labelForValue(value: T, context: Context): String abstract fun labelForValue(value: T, context: Context): String
open fun entityName(context: Context): String { open fun entityName(context: Context): String {
return getDisplayName(context) return getDisplayName(context)
} }
override fun getDisplayName(context: Context): String { fun getDisplayName(context: Context, values: List<T>): String {
val prefix = this.resId?.let { val prefix = this.resId?.let {
context.getString(it) + " " context.getString(it) + " "
} ?: "" } ?: ""
return when (listOfValues.size) { return when (values.size) {
0 -> return NULL_TEXT 0 -> return NULL_TEXT
1, 2 -> prefix + listOfValues.map { labelForValue(it, context) }.joinToString(", ") 1, 2 -> prefix + values.joinToString(", ") { labelForValue(it, context) }
else -> "${listOfValues.size} $prefix ${entityName(context)}" else -> "${values.size} $prefix ${entityName(context)}"
} }
} }
override fun getDisplayName(context: Context): String {
return getDisplayName(context, this.listOfValues)
}
override fun compareTo(other: ListOfValues<T>): Int { override fun compareTo(other: ListOfValues<T>): Int {
return listOfValues.sorted().first().compareTo(other.listOfValues.sorted().first()) return listOfValues.sorted().first().compareTo(other.listOfValues.sorted().first())
} }
@ -151,17 +173,32 @@ sealed class QueryCondition : FilterElementRow {
fun firstValue(context: Context): String? { fun firstValue(context: Context): String? {
return this.listOfValues.firstOrNull()?.let { this.labelForValue(it, context) } return this.listOfValues.firstOrNull()?.let { this.labelForValue(it, context) }
} }
} }
abstract class SingleValue<T> : ListOfValues<T>() where T : Comparable<T> { abstract class SingleValue<T>(value: T) : QueryCondition() where T : Comparable<T> {
override var listOfValues = ArrayList<T>() // override var listOfValues = mutableListOf<T>()
abstract var singleValue: T? 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>() {
open var sign: Int = 1 open var sign: Int = 1
override var operator: Operator = Operator.ANY override var operator: Operator = Operator.ANY
override var listOfValues: ArrayList<Double> = arrayListOf() override var listOfValues = mutableListOf<Double>()
override fun updateValueBy(filterCondition: FilterCondition) { override fun updateValueBy(filterCondition: FilterCondition) {
super.updateValueBy(filterCondition) super.updateValueBy(filterCondition)
listOfValues = filterCondition.getValues() listOfValues = filterCondition.getValues()
@ -174,7 +211,7 @@ sealed class QueryCondition : FilterElementRow {
abstract class ListOfInt : ListOfValues<Int>() { abstract class ListOfInt : ListOfValues<Int>() {
override var operator: Operator = Operator.ANY override var operator: Operator = Operator.ANY
override var listOfValues: ArrayList<Int> = arrayListOf() override var listOfValues = mutableListOf<Int>()
override fun updateValueBy(filterCondition: FilterCondition) { override fun updateValueBy(filterCondition: FilterCondition) {
super.updateValueBy(filterCondition) super.updateValueBy(filterCondition)
listOfValues = filterCondition.getValues() listOfValues = filterCondition.getValues()
@ -185,9 +222,15 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
abstract class UserInputListOfInt : ListOfInt() {
override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return IntValueListFilterItemRow(this, filterSectionRow)
}
}
abstract class ListOfString : ListOfValues<String>() { abstract class ListOfString : ListOfValues<String>() {
override var operator: Operator = Operator.ANY override var operator: Operator = Operator.ANY
override var listOfValues = ArrayList<String>() override var listOfValues = mutableListOf<String>()
override fun labelForValue(value: String, context: Context): String { override fun labelForValue(value: String, context: Context): String {
return value return value
} }
@ -198,46 +241,39 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
abstract class SingleDate : SingleValue<Date>() { abstract class SingleDate(date: Date) : SingleValue<Date>(date) {
override fun labelForValue(value: Date, context: Context): String { override fun labelForValue(value: Date, context: Context): String {
return value.shortDate() return value.shortDate()
} }
override var listOfValues = ArrayList<Date>() // override var listOfValues = mutableListOf<Date>()
override var singleValue: Date?
get() {
return listOfValues.firstOrNull()
}
set(value) {
listOfValues.removeAll(this.listOfValues)
value?.let { listOfValues.add(it) }
}
override fun updateValueBy(filterCondition: FilterCondition) { override fun updateValueBy(filterCondition: FilterCondition) {
super.updateValueBy(filterCondition) super.updateValueBy(filterCondition)
singleValue = filterCondition.getValue() singleValue = filterCondition.getValue()
} }
override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return DateFilterItemRow(this, filterSectionRow)
}
} }
abstract class SingleInt : SingleValue<Int>() { abstract class SingleInt(value: Int) : SingleValue<Int>(value) {
override fun labelForValue(value: Int, context: Context): String { override fun labelForValue(value: Int, context: Context): String {
return value.toString() return value.toString()
} }
override var singleValue: Int?
get() {
return listOfValues.firstOrNull()
}
set(value) {
listOfValues.removeAll(this.listOfValues)
value?.let { listOfValues.add(it) }
}
override fun updateValueBy(filterCondition: FilterCondition) { override fun updateValueBy(filterCondition: FilterCondition) {
super.updateValueBy(filterCondition) super.updateValueBy(filterCondition)
singleValue = filterCondition.getValue() singleValue = filterCondition.getValue()
} }
}
abstract class UserInputSingleInt(value: Int) : SingleInt(value) {
override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return IntFilterItemRow(this, filterSectionRow)
}
} }
override fun getDisplayName(context: Context): String { override fun getDisplayName(context: Context): String {
@ -247,7 +283,7 @@ sealed class QueryCondition : FilterElementRow {
return baseId return baseId
} }
override var filterSectionRow: FilterSectionRow = FilterSectionRow.CashOrTournament // override var filterSectionRow: FilterSectionRow = FilterSectionRow.CashOrTournament
abstract class QueryDataCondition<T : NameManageable> : ListOfString() { abstract class QueryDataCondition<T : NameManageable> : ListOfString() {
fun setObject(dataObject: T) { fun setObject(dataObject: T) {
@ -263,7 +299,7 @@ sealed class QueryCondition : FilterElementRow {
val completeLabel = when (listOfValues.size) { val completeLabel = when (listOfValues.size) {
0 -> NULL_TEXT 0 -> NULL_TEXT
1, 2 -> { 1, 2 -> {
listOfValues.map { labelForValue(realm, it) }.joinToString(", ") listOfValues.joinToString(", ") { labelForValue(realm, it) }
} }
else -> "${listOfValues.size} $entityName" else -> "${listOfValues.size} $entityName"
} }
@ -281,26 +317,29 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
interface DateTime { interface DateTime {
val showTime: Boolean val showTime: Boolean
} }
abstract class DateQuery : SingleDate(), 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 {
return singleValue?.let { return if (showTime) {
if (showTime) { singleValue.shortTime()
it.shortTime() } else {
} else { singleValue.shortDate()
it.shortDate() }
}
} ?: NULL_TEXT
} }
} }
abstract class TimeQuery : DateQuery() { abstract class UserInputSingleDate(date: Date) : SingleDate(date) {
override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return DateFilterItemRow(this, filterSectionRow)
}
}
abstract class TimeQuery(date: Date) : DateQuery(date) {
override val showTime: Boolean = true override val showTime: Boolean = true
} }
@ -343,50 +382,34 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
class AnyTournamentName() : QueryDataCondition<TournamentName>() { class AnyTournamentName : QueryDataCondition<TournamentName>() {
override val entity: Class<TournamentName> = TournamentName::class.java override val entity: Class<TournamentName> = TournamentName::class.java
constructor(tournamentName: TournamentName) : this() {
this.setObject(tournamentName)
}
override fun entityName(context: Context): String { override fun entityName(context: Context): String {
return context.getString(R.string.tournament_names) return context.getString(R.string.tournament_names)
} }
} }
class AnyTournamentFeature() : QueryDataCondition<TournamentFeature>() { class AnyTournamentFeature : QueryDataCondition<TournamentFeature>() {
override val entity: Class<TournamentFeature> = TournamentFeature::class.java override val entity: Class<TournamentFeature> = TournamentFeature::class.java
constructor(tournamentFeature: TournamentFeature) : this() {
this.setObject(tournamentFeature)
}
override fun entityName(context: Context): String { override fun entityName(context: Context): String {
return context.getString(R.string.tournament_features) return context.getString(R.string.tournament_features)
} }
} }
class AllTournamentFeature() : QueryDataCondition<TournamentFeature>() { class AllTournamentFeature : QueryDataCondition<TournamentFeature>() {
override var operator = Operator.ALL override var operator = Operator.ALL
override val entity: Class<TournamentFeature> = TournamentFeature::class.java override val entity: Class<TournamentFeature> = TournamentFeature::class.java
constructor(tournamentFeature: TournamentFeature) : this() {
this.setObject(tournamentFeature)
}
override fun entityName(context: Context): String { override fun entityName(context: Context): String {
return context.getString(R.string.tournament_features) return context.getString(R.string.tournament_features)
} }
} }
class AnyLocation() : QueryDataCondition<Location>() { class AnyLocation : QueryDataCondition<Location>() {
override val entity: Class<Location> = Location::class.java override val entity: Class<Location> = Location::class.java
constructor(location: Location) : this() {
this.setObject(location)
}
override fun entityName(context: Context): String { override fun entityName(context: Context): String {
return context.getString(R.string.locations) return context.getString(R.string.locations)
} }
@ -438,15 +461,12 @@ sealed class QueryCondition : FilterElementRow {
override fun entityName(context: Context): String { override fun entityName(context: Context): String {
return context.getString(R.string.blinds) return context.getString(R.string.blinds)
} }
}
object Last : SingleInt() { override fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
override var operator = Operator.EQUALS return FixedValueFilterItemRow(this, filterSectionRow)
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 {
@ -458,7 +478,13 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
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)
@ -469,20 +495,20 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
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 {
@ -490,14 +516,18 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
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)
} }
@ -507,19 +537,19 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
class StartedFromDate : DateQuery() { class StartedFromDate(date: Date) : DateQuery(date) {
override var operator = Operator.MORE override var operator = Operator.MORE
} }
class StartedToDate : DateQuery() { class StartedToDate(date: Date) : DateQuery(date) {
override var operator = Operator.LESS override var operator = Operator.LESS
} }
class EndedFromDate : DateQuery() { class EndedFromDate(date: Date) : DateQuery(date) {
override var operator = Operator.MORE override var operator = Operator.MORE
} }
class EndedToDate : DateQuery() { class EndedToDate(date: Date) : DateQuery(date) {
override var operator = Operator.LESS override var operator = Operator.LESS
} }
@ -530,23 +560,23 @@ sealed class QueryCondition : FilterElementRow {
} }
class AnyMonthOfYear() : ListOfInt() { class AnyMonthOfYear() : ListOfInt() {
override fun labelForValue(value: Int, context: Context): String {
return DateFormatSymbols.getInstance(Locale.getDefault()).months[value].capitalize()
}
constructor(month: Int) : this() { constructor(month: Int) : this() {
listOfValues = arrayListOf(month) listOfValues = arrayListOf(month)
} }
}
class AnyYear() : ListOfInt() {
override fun labelForValue(value: Int, context: Context): String { override fun labelForValue(value: Int, context: Context): String {
return "$value" return DateFormatSymbols.getInstance(Locale.getDefault()).months[value].capitalize()
} }
}
class AnyYear() : ListOfInt() {
constructor(year: Int) : this() { constructor(year: Int) : this() {
listOfValues = arrayListOf(year) listOfValues = arrayListOf(year)
} }
override fun labelForValue(value: Int, context: Context): String {
return "$value"
}
} }
object IsWeekDay : TrueQueryCondition() object IsWeekDay : TrueQueryCondition()
@ -564,7 +594,7 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
class PastDay : SingleInt() { class PastDay(value: Int) : UserInputSingleInt(value) {
override var operator = Operator.EQUALS override var operator = Operator.EQUALS
override val viewType: Int = RowViewType.TITLE_VALUE_CHECK.ordinal override val viewType: Int = RowViewType.TITLE_VALUE_CHECK.ordinal
@ -572,16 +602,17 @@ sealed class QueryCondition : FilterElementRow {
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 : SingleInt() { class Duration(value: Int) : UserInputSingleInt(value) {
override var operator = Operator.EQUALS override var operator = Operator.EQUALS
var minutes: Int?
var minutes: Int
get() { get() {
return singleValue return singleValue
} }
@ -589,12 +620,9 @@ sealed class QueryCondition : FilterElementRow {
singleValue = value singleValue = value
} }
val netDuration: Long? val netDuration: Long
get() { get() {
minutes?.let { return (singleValue * 60 * 1000).toLong()
return (it * 60 * 1000).toLong()
}
return null
} }
override val viewType: Int = RowViewType.TITLE_VALUE_CHECK.ordinal override val viewType: Int = RowViewType.TITLE_VALUE_CHECK.ordinal
@ -609,22 +637,12 @@ sealed class QueryCondition : FilterElementRow {
object EndDateNotNull : NotNullQueryCondition() object EndDateNotNull : NotNullQueryCondition()
object BigBlindNotNull : NotNullQueryCondition() object BigBlindNotNull : NotNullQueryCondition()
class StartedFromTime() : TimeQuery() { class StartedFromTime(date: Date) : TimeQuery(date) {
override var operator = Operator.MORE override var operator = Operator.MORE
constructor(date: Date) : this() {
singleValue = date
}
} }
class EndedToTime() : TimeQuery() { 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 {
@ -639,12 +657,8 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
class CustomFieldQuery() : QueryDataCondition<CustomField>() { class CustomFieldQuery : QueryDataCondition<CustomField>() {
override var entity: Class<CustomField> = CustomField::class.java override var entity: Class<CustomField> = CustomField::class.java
constructor(customField: CustomField) : this() {
this.setObject(customField)
}
} }
open class CustomFieldNumberQuery() : ListOfDouble(), CustomFieldRelated { open class CustomFieldNumberQuery() : ListOfDouble(), CustomFieldRelated {
@ -666,7 +680,9 @@ sealed class QueryCondition : FilterElementRow {
val completeLabel = when (listOfValues.size) { val completeLabel = when (listOfValues.size) {
0 -> return NULL_TEXT 0 -> return NULL_TEXT
1, 2 -> { 1, 2 -> {
return name + prefix + listOfValues.map { labelForValue(it, context) }.joinToString(", ") return name + prefix + listOfValues.joinToString(", ") {
labelForValue(it, context)
}
} }
else -> "${listOfValues.size} $prefix $name" else -> "${listOfValues.size} $prefix $name"
} }
@ -712,6 +728,10 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
open fun toRowWrapper(filterSectionRow: FilterSectionRow): FilterItemRow {
return FixedValueFilterItemRow(this, filterSectionRow)
}
/** /**
* main method of the enum * main method of the enum
* providing a base RealmQuery [realmQuery], the method is able to attached the corresponding query and returns the newly formed [RealmQuery] * providing a base RealmQuery [realmQuery], the method is able to attached the corresponding query and returns the newly formed [RealmQuery]
@ -762,15 +782,12 @@ sealed class QueryCondition : FilterElementRow {
.lessThanOrEqualTo(fieldName, calendar.time.endOfDay()) .lessThanOrEqualTo(fieldName, calendar.time.endOfDay())
} }
is PastDay -> { is PastDay -> {
singleValue?.let { val startDate = Date()
val startDate = Date() val calendar = Calendar.getInstance()
val calendar = Calendar.getInstance() calendar.time = startDate
calendar.time = startDate calendar.add(Calendar.DAY_OF_YEAR, -singleValue)
calendar.add(Calendar.DAY_OF_YEAR, -it) return realmQuery.greaterThanOrEqualTo(fieldName, calendar.time.startOfDay()).and()
return realmQuery.greaterThanOrEqualTo(fieldName, calendar.time.startOfDay()).and() .lessThanOrEqualTo(fieldName, startDate.endOfDay())
.lessThanOrEqualTo(fieldName, startDate.endOfDay())
}
return realmQuery
} }
is DuringThisWeek -> { is DuringThisWeek -> {
val calendar = Calendar.getInstance() val calendar = Calendar.getInstance()
@ -800,29 +817,21 @@ sealed class QueryCondition : FilterElementRow {
} }
is StartedFromTime -> { is StartedFromTime -> {
val calendar = Calendar.getInstance() val calendar = Calendar.getInstance()
singleValue?.let { calendar.time = singleValue
calendar.time = it realmQuery.greaterThanOrEqualTo(fieldName, calendar.hourMinute())
realmQuery.greaterThanOrEqualTo(fieldName, calendar.hourMinute()) if (otherQueryCondition is EndedToTime) {
if (otherQueryCondition is EndedToTime) { calendar.time = otherQueryCondition.singleValue
otherQueryCondition.singleValue?.let { endTime -> realmQuery.lessThanOrEqualTo(fieldName, calendar.hourMinute())
calendar.time = endTime
realmQuery.lessThanOrEqualTo(fieldName, calendar.hourMinute())
}
}
} }
return realmQuery return realmQuery
} }
is EndedToTime -> { is EndedToTime -> {
val calendar = Calendar.getInstance() val calendar = Calendar.getInstance()
singleValue?.let { date -> calendar.time = singleValue
calendar.time = date realmQuery.lessThanOrEqualTo(fieldName, calendar.hourMinute())
realmQuery.lessThanOrEqualTo(fieldName, calendar.hourMinute()) if (otherQueryCondition is StartedFromTime) {
if (otherQueryCondition is StartedFromTime) { calendar.time = otherQueryCondition.singleValue
otherQueryCondition.singleValue?.let { startTime -> realmQuery.greaterThanOrEqualTo(fieldName, calendar.hourMinute())
calendar.time = startTime
realmQuery.greaterThanOrEqualTo(fieldName, calendar.hourMinute())
}
}
} }
return realmQuery return realmQuery
} }
@ -846,14 +855,8 @@ sealed class QueryCondition : FilterElementRow {
return when (operator) { return when (operator) {
Operator.EQUALS -> { Operator.EQUALS -> {
when (this) { when (this) {
is SingleDate -> realmQuery.equalTo( is SingleDate -> realmQuery.equalTo(fieldName, singleValue)
fieldName, is SingleInt -> realmQuery.equalTo(fieldName, singleValue)
singleValue ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing
)
is SingleInt -> realmQuery.equalTo(
fieldName,
singleValue ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing
)
is ListOfInt -> realmQuery.equalTo(fieldName, listOfValues.first()) is ListOfInt -> realmQuery.equalTo(fieldName, listOfValues.first())
is ListOfDouble -> realmQuery.equalTo(fieldName, listOfValues.first() * sign) is ListOfDouble -> realmQuery.equalTo(fieldName, listOfValues.first() * sign)
is ListOfString -> realmQuery.equalTo(fieldName, listOfValues.first()) is ListOfString -> realmQuery.equalTo(fieldName, listOfValues.first())
@ -862,20 +865,11 @@ sealed class QueryCondition : FilterElementRow {
} }
Operator.MORE -> { Operator.MORE -> {
when (this) { when (this) {
is SingleDate -> realmQuery.greaterThanOrEqualTo( is SingleDate -> realmQuery.greaterThanOrEqualTo(fieldName, singleValue.startOfDay())
fieldName, is Duration -> realmQuery.greaterThan(fieldName, netDuration)
singleValue?.startOfDay() ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing
)
is Duration -> realmQuery.greaterThan(
fieldName,
netDuration ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing
)
is TournamentFinalPosition -> realmQuery.greaterThanOrEqualTo(fieldName, listOfValues.first()) is TournamentFinalPosition -> realmQuery.greaterThanOrEqualTo(fieldName, listOfValues.first())
is TournamentNumberOfPlayer -> realmQuery.greaterThanOrEqualTo(fieldName, listOfValues.first()) is TournamentNumberOfPlayer -> realmQuery.greaterThanOrEqualTo(fieldName, listOfValues.first())
is SingleInt -> realmQuery.greaterThan( is SingleInt -> realmQuery.greaterThan(fieldName, singleValue)
fieldName,
singleValue ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing
)
is ListOfInt -> realmQuery.greaterThan(fieldName, listOfValues.first()) is ListOfInt -> realmQuery.greaterThan(fieldName, listOfValues.first())
is NetAmountLost -> realmQuery.lessThan(fieldName, listOfValues.first() * -1) is NetAmountLost -> realmQuery.lessThan(fieldName, listOfValues.first() * -1)
is ListOfDouble -> realmQuery.greaterThan(fieldName, listOfValues.first() * sign) is ListOfDouble -> realmQuery.greaterThan(fieldName, listOfValues.first() * sign)
@ -884,20 +878,11 @@ sealed class QueryCondition : FilterElementRow {
} }
Operator.LESS -> { Operator.LESS -> {
when (this) { when (this) {
is SingleDate -> realmQuery.lessThanOrEqualTo( is SingleDate -> realmQuery.lessThanOrEqualTo(fieldName, singleValue.endOfDay())
fieldName, is Duration -> realmQuery.lessThan(fieldName, netDuration)
singleValue?.endOfDay() ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing
)
is Duration -> realmQuery.lessThan(
fieldName,
netDuration ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing
)
is TournamentFinalPosition -> realmQuery.lessThanOrEqualTo(fieldName, listOfValues.first()) is TournamentFinalPosition -> realmQuery.lessThanOrEqualTo(fieldName, listOfValues.first())
is TournamentNumberOfPlayer -> realmQuery.lessThanOrEqualTo(fieldName, listOfValues.first()) is TournamentNumberOfPlayer -> realmQuery.lessThanOrEqualTo(fieldName, listOfValues.first())
is SingleInt -> realmQuery.lessThan( is SingleInt -> realmQuery.lessThan(fieldName, singleValue)
fieldName,
singleValue ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing
)
is ListOfInt -> realmQuery.lessThan(fieldName, listOfValues.first()) is ListOfInt -> realmQuery.lessThan(fieldName, listOfValues.first())
is NetAmountLost -> { is NetAmountLost -> {
realmQuery.greaterThan(fieldName, listOfValues.first() * -1) realmQuery.greaterThan(fieldName, listOfValues.first() * -1)
@ -947,6 +932,7 @@ sealed class QueryCondition : FilterElementRow {
} }
} }
override val viewType: Int override val viewType: Int
get() { get() {
return when (this) { return when (this) {

@ -17,6 +17,7 @@ import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterItemRow
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
@ -89,22 +90,25 @@ open class Filter : RealmObject(), RowRepresentable, Editable, Deletable, Counta
return FilterableType.ALL return FilterableType.ALL
} }
fun createOrUpdateFilterConditions(filterConditionRows: ArrayList<QueryCondition>) { fun createOrUpdateFilterConditions(filterConditionRows: List<FilterItemRow>) {
Timber.d("list of querys saving: ${filterConditionRows.map { it.id }}")
Timber.d("list of querys saving: ${filterConditionRows.map { it.queryCondition?.id }}")
Timber.d("list of querys previous: ${this.filterConditions.map { it.queryCondition.id }}") Timber.d("list of querys previous: ${this.filterConditions.map { it.queryCondition.id }}")
filterConditionRows filterConditionRows
.map { .mapNotNull {
it.groupId it.queryCondition?.groupId
} }
.distinct() .distinct()
.forEach { groupId -> .forEach { groupId ->
filterConditionRows filterConditionRows
.filter { .filter {
it.groupId == groupId it.queryCondition?.groupId == groupId
} }
.apply { .apply {
Timber.d("list of querys: ${this.map { it.id }}") val conditions = this.mapNotNull { it.queryCondition }
val newFilterCondition = FilterCondition(this) Timber.d("list of querys: ${conditions.map { it.id }}")
val newFilterCondition = FilterCondition(conditions, this.first().filterSectionRow)
val previousCondition = filterConditions.filter { val previousCondition = filterConditions.filter {
it.filterName == newFilterCondition.filterName && it.operator == newFilterCondition.operator it.filterName == newFilterCondition.filterName && it.operator == newFilterCondition.operator
} }
@ -132,19 +136,13 @@ open class Filter : RealmObject(), RowRepresentable, Editable, Deletable, Counta
Timber.d("list of saved queries ${filterConditions.map { it.queryCondition.id }}") Timber.d("list of saved queries ${filterConditions.map { it.queryCondition.id }}")
Timber.d("list of contains ${filterElementRow.id}") Timber.d("list of contains ${filterElementRow.id}")
val contained = filterConditions.flatMap { it.queryCondition.id }.contains(filterElementRow.id.first()) val contained = filterConditions.flatMap { it.queryCondition.id }.contains(filterElementRow.id.first())
Timber.d("list of : $contained") Timber.d("is contained: $contained")
return contained return contained
} }
/** fun filterCondition(filterElementRow: QueryCondition): FilterCondition? {
* Get the saved value for the given [filterElementRow] return filterConditions.firstOrNull {
*/ it.queryCondition.id.contains(filterElementRow.id.first())
fun loadValueForElement(filterElementRow: QueryCondition) {
val filtered = filterConditions.filter {
it.queryCondition.id == filterElementRow.id
}
if (filtered.isNotEmpty()) {
return filterElementRow.updateValueBy(filtered.first())
} }
} }

@ -4,17 +4,18 @@ import io.realm.RealmList
import io.realm.RealmObject import io.realm.RealmObject
import net.pokeranalytics.android.exceptions.PokerAnalyticsException import net.pokeranalytics.android.exceptions.PokerAnalyticsException
import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
open class FilterCondition() : RealmObject() { open class FilterCondition() : RealmObject() {
private constructor(filterName:String, sectionName:String) : this() { private constructor(filterName: String, sectionName: String) : this() {
this.filterName = filterName this.filterName = filterName
this.sectionName = sectionName this.sectionName = sectionName
} }
constructor(filterElementRows: List<QueryCondition>) : this(filterElementRows.first().baseId, filterElementRows.first().filterSectionRow.name) { constructor(filterElementRows: List<QueryCondition>, section: FilterSectionRow) : this(filterElementRows.first().baseId, section.name) {
val row = filterElementRows.first() val row = filterElementRows.first()
this.filterName ?: throw PokerAnalyticsException.FilterElementUnknownName this.filterName ?: throw PokerAnalyticsException.FilterElementUnknownName
this.operator = row.operator.ordinal this.operator = row.operator.ordinal
@ -22,8 +23,8 @@ open class FilterCondition() : RealmObject() {
this.stringValue = row.customFieldId this.stringValue = row.customFieldId
} }
when (row) { when (row) {
is QueryCondition.SingleInt -> this.setValue(row.singleValue?:throw PokerAnalyticsException.FilterElementExpectedValueMissing) is QueryCondition.SingleInt -> this.setValue(row.singleValue)
is QueryCondition.SingleDate -> this.setValue(row.singleValue?:throw PokerAnalyticsException.FilterElementExpectedValueMissing) is QueryCondition.SingleDate -> this.setValue(row.singleValue)
is QueryCondition.ListOfDouble -> this.setValues(filterElementRows.flatMap { (it as QueryCondition.ListOfDouble).listOfValues }) is QueryCondition.ListOfDouble -> this.setValues(filterElementRows.flatMap { (it as QueryCondition.ListOfDouble).listOfValues })
is QueryCondition.ListOfInt -> this.setValues(filterElementRows.flatMap { (it as QueryCondition.ListOfInt).listOfValues }) is QueryCondition.ListOfInt -> this.setValues(filterElementRows.flatMap { (it as QueryCondition.ListOfInt).listOfValues })
is QueryCondition.ListOfString -> this.setValues(filterElementRows.flatMap { (it as QueryCondition.ListOfString).listOfValues }) is QueryCondition.ListOfString -> this.setValues(filterElementRows.flatMap { (it as QueryCondition.ListOfString).listOfValues })
@ -48,7 +49,7 @@ open class FilterCondition() : RealmObject() {
var stringValue: String? = null var stringValue: String? = null
var operator: Int? = null var operator: Int? = null
inline fun <reified T:Any > getValues(): ArrayList < T > { inline fun <reified T> getValues(): ArrayList <T> {
return when (T::class) { return when (T::class) {
Int::class -> ArrayList<T>().apply { intValues?.map { add(it as T) } } Int::class -> ArrayList<T>().apply { intValues?.map { add(it as T) } }
Double::class -> ArrayList<T>().apply { doubleValues?.map { add(it as T) } } Double::class -> ArrayList<T>().apply { doubleValues?.map { add(it as T) } }
@ -57,7 +58,17 @@ open class FilterCondition() : RealmObject() {
} }
} }
inline fun <reified T:Any > getValue(): T { fun <T> getv(clazz: Class<T>) : T {
return when (clazz) {
Int::class -> intValue ?: 0
Double::class -> doubleValue?: 0.0
Date::class -> dateValue ?: Date()
String::class -> stringValue ?: ""
else -> throw PokerAnalyticsException.QueryValueMapUnexpectedValue
} as T
}
inline fun <reified T> getValue(): T {
return when (T::class) { return when (T::class) {
Int::class -> intValue ?: 0 Int::class -> intValue ?: 0
Double::class -> doubleValue?: 0.0 Double::class -> doubleValue?: 0.0
@ -91,4 +102,5 @@ open class FilterCondition() : RealmObject() {
fun setValue(value:String) { fun setValue(value:String) {
stringValue = value stringValue = value
} }
} }

@ -168,8 +168,8 @@ 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? = this.currentFilter(this.requireContext(), realm)?.let {
if (it.filterableType == currentFilterable) { it } else { null } if (it.filterableType == currentFilterable) { it } else { null }
} }
val allStats: List<Stat> = listOf( val allStats: List<Stat> = listOf(
Stat.NET_RESULT, Stat.NET_RESULT,

@ -144,7 +144,7 @@ abstract class BaseFragment : Fragment() {
isClearable: Boolean? = true, isClearable: Boolean? = true,
currentCurrency: Currency? = null, currentCurrency: Currency? = null,
isDeletable: Boolean? = false, isDeletable: Boolean? = false,
valueHasPlaceholder: Boolean? = null, valueHasPlaceholder: Boolean? = true,
alternativeLabels: Boolean = false) { alternativeLabels: Boolean = false) {
BottomSheetFragment.create(activity as BaseActivity, BottomSheetFragment.create(activity as BaseActivity,

@ -29,7 +29,7 @@ class BottomSheetEditTextFragment : BottomSheetFragment() {
*/ */
private fun initUI() { private fun initUI() {
val data = getDescriptors() ?: throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor not found") val data = getDescriptors() ?: throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor not found for $this")
if (data.size != 1) { if (data.size != 1) {
throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor inconsistency") throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor inconsistency")
} }

@ -60,7 +60,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
isClearable: Boolean? = true, isClearable: Boolean? = true,
currentCurrency: Currency? = null, currentCurrency: Currency? = null,
isDeletable: Boolean? = false, isDeletable: Boolean? = false,
valueHasPlaceholder: Boolean? = null, valueHasPlaceholder: Boolean? = true,
alternativeLabels: Boolean = false alternativeLabels: Boolean = false
): BottomSheetFragment { ): BottomSheetFragment {
val bottomSheetFragment = newInstance(row.bottomSheetType) val bottomSheetFragment = newInstance(row.bottomSheetType)

@ -3,7 +3,7 @@ package net.pokeranalytics.android.ui.modules.calendar
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProvider
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedResults import net.pokeranalytics.android.calculus.ComputedResults
import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.filter.QueryCondition
@ -13,7 +13,7 @@ import net.pokeranalytics.android.ui.activity.components.BaseActivity
class CalendarDetailsActivity : BaseActivity() { class CalendarDetailsActivity : BaseActivity() {
private val model: CalendarDetailsViewModel by lazy { private val model: CalendarDetailsViewModel by lazy {
ViewModelProviders.of(this).get(CalendarDetailsViewModel::class.java) ViewModelProvider(this).get(CalendarDetailsViewModel::class.java)
} }
companion object { companion object {

@ -1,6 +1,5 @@
package net.pokeranalytics.android.ui.modules.filter package net.pokeranalytics.android.ui.modules.filter
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -10,34 +9,38 @@ import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_filter_details.* import kotlinx.android.synthetic.main.fragment_filter_details.*
import kotlinx.android.synthetic.main.fragment_filter_details.view.* import kotlinx.android.synthetic.main.fragment_filter_details.view.*
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.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.helpers.DateTimePickerManager import net.pokeranalytics.android.ui.helpers.DateTimePickerManager
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow import net.pokeranalytics.android.ui.view.rowrepresentable.*
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow
import net.pokeranalytics.android.util.NULL_TEXT
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import kotlin.collections.ArrayList
open class FilterDetailsFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { open class FilterDetailsFragment : RealmFragment(), RowRepresentableDelegate {
val model: FilterViewModel by lazy { private val activityModel: FilterViewModel by lazy {
ViewModelProvider(requireActivity()).get(FilterViewModel::class.java) ViewModelProvider(requireActivity()).get(FilterViewModel::class.java)
} }
private lateinit var model: FilterDetailsViewModel
private lateinit var rowRepresentableAdapter: RowRepresentableAdapter private lateinit var rowRepresentableAdapter: RowRepresentableAdapter
// private var currentFilter: Filter? = null companion object {
private var rows: ArrayList<RowRepresentable> = ArrayList()
private var rowsForFilterSubcategoryRow: HashMap<FilterSectionRow, ArrayList<RowRepresentable>> = HashMap()
private val selectedRows = ArrayList<QueryCondition>() fun newInstance(categoryRow: FilterCategoryRow): FilterDetailsFragment {
val fragment = FilterDetailsFragment()
val bundle = Bundle()
bundle.putInt(BundleKey.DATA_TYPE.value, categoryRow.ordinal)
fragment.arguments = bundle
return fragment
}
}
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)
@ -53,11 +56,8 @@ open class FilterDetailsFragment : RealmFragment(), StaticRowRepresentableDataSo
override fun onBackPressed() { override fun onBackPressed() {
super.onBackPressed() super.onBackPressed()
saveData() saveData()
// requireFragmentManager().popBackStackImmediate("f1", 0)
// requireFragmentManager().popBackStackImmediate()
} }
/** /**
* Init UI * Init UI
*/ */
@ -80,39 +80,24 @@ open class FilterDetailsFragment : RealmFragment(), StaticRowRepresentableDataSo
*/ */
private fun initData() { private fun initData() {
// this.arguments?.let { bundle -> this.arguments?.let { bundle ->
//
// bundle.getString(BundleKey.PRIMARY_KEY.value)?.let { filterId ->
// this.currentFilter = getRealm().findById(filterId)
// }
//
// val category = bundle.getInt(BundleKey.DATA_TYPE.value)
// this.filterCategoryRow = FilterCategoryRow.values()[category]
//
// } ?: throw PAIllegalStateException("Missing bundle")
//currentFilter = Filter.getFilterBydId(getRealm(), primaryKey) val filter = this.activityModel.currentFilter ?: throw PAIllegalStateException("Filter is null")
// currentFilter = FiltersFragment.currentFilter val category = bundle.getInt(BundleKey.DATA_TYPE.value)
val categoryRow = FilterCategoryRow.values()[category]
Timber.d("Category row = $categoryRow")
Timber.d(">> Filter = ${this.model.currentFilter}") val factory = FilterDetailsViewModelFactory(filter, categoryRow)
Timber.d("selectedRow = ${this.model.selectedCategoryRow}") this.model = ViewModelProvider(this, factory).get(FilterDetailsViewModel::class.java)
val filterCategoryRow = this.model.filterCategoryRow } ?: throw PAIllegalStateException("Missing bundle")
this.appBar.toolbar.title = filterCategoryRow.localizedTitle(requireContext()) Timber.d(">> Filter = ${this.activityModel.currentFilter}")
Timber.d("selectedRow = ${this.activityModel.selectedCategoryRow}")
this.rows.clear() this.appBar.toolbar.title = this.activityModel.selectedCategoryRow?.localizedTitle(requireContext())
this.rowsForFilterSubcategoryRow.clear()
this.rows.addAll(filterCategoryRow.filterElements)
this.rows.forEach { element ->
if (element is QueryCondition && this.model.currentFilter?.contains(element) == true) {
this.model.currentFilter?.loadValueForElement(element)
this.selectedRows.add(element)
}
}
this.rowRepresentableAdapter = RowRepresentableAdapter(this, this) this.rowRepresentableAdapter = RowRepresentableAdapter(this.model, this)
this.recyclerView.adapter = rowRepresentableAdapter this.recyclerView.adapter = rowRepresentableAdapter
} }
@ -124,49 +109,31 @@ open class FilterDetailsFragment : RealmFragment(), StaticRowRepresentableDataSo
return return
} }
when (row) { (row as? FixedValueFilterItemRow)?.let {
is QueryCondition.DateQuery -> DateTimePickerManager.create( when (val condition = it.rawCondition) {
requireContext(), is QueryCondition.DateQuery -> DateTimePickerManager.create(
row, requireContext(),
this, row,
row.singleValue, this,
onlyDate = !row.showTime, (row as DateFilterItemRow).value,
onlyTime = row.showTime onlyDate = !condition.showTime,
) onlyTime = condition.showTime
is QueryCondition.Duration -> { )
var hours: String? = null is QueryCondition.Duration -> {
var minutes: String? = null val hours = (condition.minutes / 60).toString()
row.minutes?.let { val minutes = (condition.minutes % 60).toString()
hours = if (it / 60 > 0) (it / 60).toString() else null val data = row.editingDescriptors(mapOf("hours" to hours, "minutes" to minutes))
minutes = if (it % 60 > 0) (it % 60).toString() else null showBottomSheet(row, this, data, true)
} }
val data = row.editingDescriptors(mapOf("hours" to hours, "minutes" to minutes)) is QueryCondition.SingleValue<*>, is QueryCondition.ListOfValues<*> -> {
showBottomSheet(row, this, data, true) val valueAsString = (row as FilterItemRow).singleValue?.toString()
} val data = row.editingDescriptors(mapOf("valueAsString" to valueAsString))
is QueryCondition.ListOfValues<*> -> { showBottomSheet(row, this, data, true, valueHasPlaceholder = true)
var valueAsString: String? = null
row.listOfValues.firstOrNull()?.let {
valueAsString = row.listOfValues.firstOrNull()?.toString()
} }
val data = row.editingDescriptors(mapOf("valueAsString" to valueAsString)) else -> { }
showBottomSheet(row, this, data, true)
} }
} }
}
override fun charSequenceForRow(row: RowRepresentable, context: Context): CharSequence {
return when (row) {
is QueryCondition.ListOfValues<*> -> row.firstValue(context)
else -> super.charSequenceForRow(row, context, 0)
} ?: NULL_TEXT
}
override fun isSelected(
position: Int,
row: RowRepresentable,
tag: Int
): Boolean {
return selectedRows.contains(row)
} }
override fun onRowValueChanged(value: Any?, row: RowRepresentable) { override fun onRowValueChanged(value: Any?, row: RowRepresentable) {
@ -174,80 +141,61 @@ open class FilterDetailsFragment : RealmFragment(), StaticRowRepresentableDataSo
Timber.d("onRowValueChanged: $row $value") Timber.d("onRowValueChanged: $row $value")
when (row) { when (row) {
is QueryCondition.DateQuery -> row.singleValue = if (value != null && value is Date) value else null is DateFilterItemRow -> {
is QueryCondition.Duration -> { row.value = value as? Date
if (value is ArrayList<*>) { }
val hours: Int? = try { is IntFilterItemRow -> {
(value[0] as String?)?.toInt() when (value) {
} catch (e: Exception) { is String -> {
null row.value = value.toInt()
}
val minutes = try {
(value[1] as String?)?.toInt()
} catch (e: Exception) {
null
} }
if (hours != null && minutes != null) { is ArrayList<*> -> {
row.minutes = hours * 60 + minutes val hours: Int? = try {
} else if (hours != null) { (value[0] as String?)?.toInt()
row.minutes = hours * 60 } catch (e: Exception) {
} else if (minutes != null) { null
row.minutes = minutes }
val minutes = try {
(value[1] as String?)?.toInt()
} catch (e: Exception) {
null
}
if (hours != null && minutes != null) {
row.value = hours * 60 + minutes
} else if (hours != null) {
row.value = hours * 60
} else if (minutes != null) {
row.value = minutes
}
} }
} else { else -> { row.value = null }
row.minutes = null
} }
} }
is QueryCondition.SingleInt -> row.singleValue = if (value != null && value is String) value.toInt() else null is DoubleValueListFilterItemRow -> {
is QueryCondition.ListOfDouble -> row.listOfValues = arrayListOf<Double>().apply { val string = value as String
if (value != null && value is String) this.add(value.toDouble()) row.add(string.toDouble())
} }
is QueryCondition.ListOfInt -> row.listOfValues = arrayListOf<Int>().apply { is IntValueListFilterItemRow -> {
if (value != null && value is String) this.add(value.toInt()) val string = value as String
row.add(string.toInt())
} }
is QueryCondition.ListOfString -> row.listOfValues = arrayListOf<String>().apply { is StringValueListFilterItemRow -> {
if (value != null && value is String) this.add(value) row.add(value as String)
} }
} }
// Remove the row before updating the selected rows list // Remove the row before updating the selected rows list
selectedRows.remove(row as FilterElementRow) this.model.selectedRows.remove(row as FilterItemRow)
updateRowsSelection(row, value == null) updateRowsSelection(row, value == null)
} }
override fun adapterRows(): List<RowRepresentable>? {
return rows
}
override fun viewTypeForPosition(position: Int): Int {
val rowViewType = rowRepresentableForPosition(position)?.viewType ?: -1
return if (rowViewType != -1) rowViewType else RowViewType.TITLE_CHECK.ordinal
}
/** /**
* Update rows selection * Update rows selection
*/ */
private fun updateRowsSelection(row: RowRepresentable, forceDeselection: Boolean = false) { private fun updateRowsSelection(row: RowRepresentable, forceDeselection: Boolean = false) {
if (selectedRows.contains(row) || forceDeselection) { this.model.updateRowsSelection(this.rowRepresentableAdapter, row, forceDeselection)
selectedRows.remove(row)
} else {
if (row is FilterElementRow) {
row.sectionToExclude?.let { filterSectionToExclude ->
val excludedFilters = selectedRows.filter {
filterSectionToExclude.contains(it.filterSectionRow)
}
excludedFilters.forEach {
selectedRows.remove(it)
rowRepresentableAdapter.refreshRow(it)
}
}
selectedRows.add(row as QueryCondition)
}
}
println("list of selected rows : $selectedRows")
// Update UI // Update UI
this.rowRepresentableAdapter.refreshRow(row) this.rowRepresentableAdapter.refreshRow(row)
@ -258,18 +206,23 @@ open class FilterDetailsFragment : RealmFragment(), StaticRowRepresentableDataSo
*/ */
private fun saveData() { private fun saveData() {
val currentFilter = this.model.currentFilter val currentFilter = this.activityModel.currentFilter
//TODO: Save currentFilter details data //TODO: Save currentFilter details data
Timber.d("Save data for queryWith: ${currentFilter?.id}") Timber.d("Save data for queryWith: ${currentFilter?.id}")
this.selectedRows.forEach { this.model.selectedRows.forEach {
Timber.d("Selected rows: $it") Timber.d("Selected rows: $it")
} }
getRealm().executeTransaction { this.activityModel.selectedCategoryRow?.let { category ->
currentFilter?.remove(this.model.filterCategoryRow)
currentFilter?.createOrUpdateFilterConditions(this.selectedRows) getRealm().executeTransaction {
} currentFilter?.remove(category)
val validConditions = this.model.selectedRows.filter { it.queryCondition != null }
currentFilter?.createOrUpdateFilterConditions(validConditions)
}
}
currentFilter?.filterConditions?.forEach { currentFilter?.filterConditions?.forEach {
Timber.d("Condition: $it") Timber.d("Condition: $it")
} }

@ -0,0 +1,96 @@
package net.pokeranalytics.android.ui.modules.filter
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterItemRow
import net.pokeranalytics.android.util.NULL_TEXT
import timber.log.Timber
class FilterDetailsViewModelFactory(var filter: Filter, private var categoryRow: FilterCategoryRow): ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return FilterDetailsViewModel(categoryRow, filter) as T
}
}
class FilterDetailsViewModel(categoryRow: FilterCategoryRow, var filter: Filter) : ViewModel(), StaticRowRepresentableDataSource {
private var rows: ArrayList<RowRepresentable> = ArrayList()
val selectedRows = ArrayList<FilterItemRow>()
init {
this.rows.addAll(categoryRow.filterElements)
this.defineSelectedItems()
}
override fun adapterRows(): List<RowRepresentable>? {
return this.rows
}
override fun charSequenceForRow(row: RowRepresentable, context: Context): CharSequence {
return when (row) {
is FilterItemRow -> {
row.valueFormatted(context)
}
else -> super.charSequenceForRow(row, context, 0)
} ?: NULL_TEXT
}
override fun isSelected(position: Int, row: RowRepresentable, tag: Int): Boolean {
return this.selectedRows.contains(row)
}
override fun viewTypeForPosition(position: Int): Int {
val rowRepresentable = rowRepresentableForPosition(position)
val rowViewType = rowRepresentable?.viewType ?: -1
// Timber.d("found viewtype = $rowViewType, rr = $rowRepresentable")
return if (rowViewType != -1) rowViewType else RowViewType.TITLE_CHECK.ordinal
}
private fun defineSelectedItems() {
this.rows.filterIsInstance<FilterItemRow>().forEach { item ->
val condition = item.rawCondition
Timber.d("condition id: ${condition.id}")
this.filter.filterCondition(condition)?.let {
item.updateValue(it)
this.selectedRows.add(item)
}
}
}
fun updateRowsSelection(adapter: RowRepresentableAdapter, row: RowRepresentable, forceDeselection: Boolean = false) {
if (this.selectedRows.contains(row) || forceDeselection) {
this.selectedRows.remove(row)
} else {
if (row is FilterItemRow) {
row.sectionToExclude?.let { filterSectionToExclude ->
val excludedFilters = this.selectedRows.filter {
filterSectionToExclude.contains(it.filterSectionRow)
}
excludedFilters.forEach {
this.selectedRows.remove(it)
adapter.refreshRow(it)
}
}
this.selectedRows.add(row)
}
}
}
}

@ -34,6 +34,7 @@ enum class FilterableType(override var uniqueIdentifier: Int) : IntIdentifiable
} }
interface FilterHandler { interface FilterHandler {
companion object { companion object {
const val INTENT_FILTER_UPDATE_FILTER_UI = "net.pokeranalytics.android.UPDATE_FILTER_UI" const val INTENT_FILTER_UPDATE_FILTER_UI = "net.pokeranalytics.android.UPDATE_FILTER_UI"
} }
@ -55,8 +56,7 @@ interface FilterHandler {
// Send broadcast // Send broadcast
val intent = Intent() val intent = Intent()
intent.action = intent.action = INTENT_FILTER_UPDATE_FILTER_UI
INTENT_FILTER_UPDATE_FILTER_UI
context.sendBroadcast(intent) context.sendBroadcast(intent)
} }
@ -70,7 +70,6 @@ interface FilterHandler {
var currentFilterable: FilterableType var currentFilterable: FilterableType
/** /**
* Manage filters * Manage filters
*/ */

@ -20,14 +20,10 @@ class FilterViewModel : ViewModel(), StaticRowRepresentableDataSource {
var filterCopy: Filter? = null var filterCopy: Filter? = null
private var categoryRows: ArrayList<RowRepresentable> = ArrayList() private var categoryRows: ArrayList<RowRepresentable> = ArrayList()
var primaryKey: String? = null var primaryKey: String? = null
var selectedCategoryRow: RowRepresentable? = null
var isUpdating = false
// Details var selectedCategoryRow: FilterCategoryRow? = null
val filterCategoryRow: FilterCategoryRow
get() { var isUpdating = false
return this.selectedCategoryRow as FilterCategoryRow
}
fun init(realm: Realm) { fun init(realm: Realm) {

@ -6,8 +6,10 @@ import android.os.Bundle
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.ui.activity.components.BaseActivity import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.fragment.components.BaseFragment import net.pokeranalytics.android.ui.fragment.components.BaseFragment
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
class FiltersActivity : BaseActivity() { class FiltersActivity : BaseActivity() {
@ -88,23 +90,17 @@ class FiltersActivity : BaseActivity() {
this.model.filterableType = FilterableType.valueByIdentifier(uniqueIdentifier) this.model.filterableType = FilterableType.valueByIdentifier(uniqueIdentifier)
val filtersFragment = FiltersFragment() val filtersFragment = FiltersFragment()
// val bundle = Bundle()
// bundle.putString(BaseFragment.BundleKey.PRIMARY_KEY.value, filterId)
// bundle.putInt(BaseFragment.BundleKey.DATA_TYPE.value, uniqueIdentifier)
// fragment.arguments = bundle
// fragment.setData(filterId, filterableType)
val fragmentTransaction = this.supportFragmentManager.beginTransaction() val fragmentTransaction = this.supportFragmentManager.beginTransaction()
fragmentTransaction.add(R.id.container, filtersFragment, Tag.CATEGORIES.identifier) fragmentTransaction.add(R.id.container, filtersFragment, Tag.CATEGORIES.identifier)
// fragmentTransaction.addToBackStack(null)
fragmentTransaction.commit() fragmentTransaction.commit()
filtersFragment.updateMostUsedFiltersVisibility(!hideMostUsedFilters) filtersFragment.updateMostUsedFiltersVisibility(!hideMostUsedFilters)
} }
fun showDetailsFragment() { fun showDetailsFragment(categoryRow: FilterCategoryRow) {
val detailsFragment = FilterDetailsFragment() val detailsFragment = FilterDetailsFragment.newInstance(categoryRow)
val fragmentTransaction = this.supportFragmentManager.beginTransaction() val fragmentTransaction = this.supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.container, detailsFragment) fragmentTransaction.replace(R.id.container, detailsFragment)

@ -21,6 +21,7 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.extensions.px import net.pokeranalytics.android.ui.extensions.px
import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
import net.pokeranalytics.android.util.Preferences import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.extensions.sorted import net.pokeranalytics.android.util.extensions.sorted
import timber.log.Timber import timber.log.Timber
@ -78,9 +79,6 @@ open class FiltersFragment : RealmFragment(), RowRepresentableDelegate {
this.model.selectedCategoryRow?.let { this.model.selectedCategoryRow?.let {
rowRepresentableAdapter.refreshRow(it) rowRepresentableAdapter.refreshRow(it)
} }
// this.rowRepresentableAdapter.notifyDataSetChanged()
} }
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
@ -132,12 +130,6 @@ open class FiltersFragment : RealmFragment(), RowRepresentableDelegate {
*/ */
private fun initData() { private fun initData() {
// this.arguments?.let { bundle ->
// this.model.primaryKey = bundle.getString(BundleKey.PRIMARY_KEY.value)
// val type = bundle.getInt(BundleKey.DATA_TYPE.value)
// this.model.filterableType = FilterableType.valueByIdentifier(type)
// } ?: throw PAIllegalStateException("Missing bundle")
this.model.init(getRealm()) this.model.init(getRealm())
this.rowRepresentableAdapter = RowRepresentableAdapter(this.model, this) this.rowRepresentableAdapter = RowRepresentableAdapter(this.model, this)
@ -148,17 +140,10 @@ open class FiltersFragment : RealmFragment(), RowRepresentableDelegate {
override fun onRowSelected(position: Int, row: RowRepresentable, tag: Int) { override fun onRowSelected(position: Int, row: RowRepresentable, tag: Int) {
super.onRowSelected(position, row, tag) super.onRowSelected(position, row, tag)
this.model.selectedCategoryRow = row val categoryRow = row as FilterCategoryRow
this.model.currentFilter?.id?.let { _ -> this.model.selectedCategoryRow = categoryRow
this.model.currentFilter?.let { _ ->
(activity as FiltersActivity).showDetailsFragment() (activity as FiltersActivity).showDetailsFragment(categoryRow)
// this.model.filterCategoryRow = row as FilterCategoryRow
// FilterDetailsActivity.newInstanceForResult(
// this, filterId, (row as FilterCategoryRow).ordinal,
// REQUEST_CODE_FILTER_DETAILS
// )
} }
} }

@ -24,15 +24,6 @@ class FiltersListActivity : BaseActivity() {
companion object { companion object {
// fun newInstance(context: Context, dataType: Int) {
// context.startActivity(
// getIntent(
// context,
// dataType
// )
// )
// }
fun newSelectInstance(fragment: Fragment, showAddButton: Boolean = true) { fun newSelectInstance(fragment: Fragment, showAddButton: Boolean = true) {
val context = fragment.requireContext() val context = fragment.requireContext()
fragment.startActivityForResult( fragment.startActivityForResult(
@ -74,8 +65,6 @@ class FiltersListActivity : BaseActivity() {
this.model.showAddButton = showAddButton this.model.showAddButton = showAddButton
// fragment.setData(dataType)
// fragment.updateUI(showAddButton)
} }
} }

@ -63,7 +63,13 @@ enum class FilterCategoryRow(override val resId: Int?, override val viewType: In
val filterElements: List<RowRepresentable> val filterElements: List<RowRepresentable>
get() { get() {
return filterSectionRows.flatMap { return filterSectionRows.flatMap {
it.filterElements val items = it.filterItems
val list = mutableListOf<RowRepresentable>()
if (items.isNotEmpty()) {
list.add(it)
list.addAll(it.filterItems)
}
list
} }
} }

@ -1,61 +0,0 @@
package net.pokeranalytics.android.ui.view.rowrepresentable
import android.text.InputType
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.RowViewType
import java.util.*
interface FilterElementRow : RowRepresentable {
override fun editingDescriptors(map: Map<String, Any?>): ArrayList<RowRepresentableEditDescriptor>? {
return when (this) {
is QueryCondition.Duration -> {
val hours: String? by map
val minutes: String? by map
arrayListOf(
RowRepresentableEditDescriptor(hours, R.string.hour, inputType = InputType.TYPE_CLASS_NUMBER),
RowRepresentableEditDescriptor(minutes, R.string.minute, inputType = InputType.TYPE_CLASS_NUMBER)
)
}
is QueryCondition.ListOfValues<*> -> {
val valueAsString: String? by map
val hint = when (this.operator) {
QueryCondition.Operator.MORE, QueryCondition.Operator.LESS -> {
when (this) {
is QueryCondition.CustomFieldNumberQuery -> R.string.value
is QueryCondition.CustomFieldAmountQuery -> R.string.amount
else -> this.filterSectionRow.resId
}
}
else -> this.resId
}
arrayListOf(
RowRepresentableEditDescriptor(valueAsString, hint, inputType = InputType.TYPE_CLASS_NUMBER)
)
}
else -> super.editingDescriptors(map)
}
}
var filterSectionRow: FilterSectionRow
val sectionToExclude: List<FilterSectionRow>?
get() {
val excluded = arrayListOf<FilterSectionRow>()
if (!this.filterSectionRow.allowMultiSelection) {
excluded.add(this.filterSectionRow)
}
this.filterSectionRow.exclusiveWith?.let { exclusives ->
excluded.addAll(exclusives)
}
if (excluded.size > 0) {
return excluded
}
return null
}
}

@ -0,0 +1,197 @@
package net.pokeranalytics.android.ui.view.rowrepresentable
import android.content.Context
import android.text.InputType
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.realm.FilterCondition
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.util.NULL_TEXT
import java.util.*
interface FilterItemRow : RowRepresentable {
val rawCondition: QueryCondition
val queryCondition: QueryCondition?
var filterSectionRow: FilterSectionRow
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>?
get() {
val excluded = arrayListOf<FilterSectionRow>()
if (!this.filterSectionRow.allowMultiSelection) {
excluded.add(this.filterSectionRow)
}
this.filterSectionRow.exclusiveWith?.let { exclusives ->
excluded.addAll(exclusives)
}
if (excluded.size > 0) {
return excluded
}
return null
}
// Row Representable
override fun getDisplayName(context: Context): String {
return this.rawCondition.getDisplayName(context)
}
override val resId: Int?
get() { return this.rawCondition.resId }
override val viewType: Int
get() { return this.rawCondition.viewType }
override val bottomSheetType: BottomSheetType
get() { return this.rawCondition.bottomSheetType }
override fun editingDescriptors(map: Map<String, Any?>): ArrayList<RowRepresentableEditDescriptor>? {
return when (this.rawCondition) {
is QueryCondition.Duration -> {
val hours: String? by map
val minutes: String? by map
arrayListOf(
RowRepresentableEditDescriptor(hours, R.string.hour, inputType = InputType.TYPE_CLASS_NUMBER),
RowRepresentableEditDescriptor(minutes, R.string.minute, inputType = InputType.TYPE_CLASS_NUMBER)
)
}
is QueryCondition.SingleValue<*>, is QueryCondition.ListOfValues<*> -> {
val valueAsString: String? by map
val hint = when (this.queryCondition?.operator) {
QueryCondition.Operator.MORE, QueryCondition.Operator.LESS -> {
when (this.queryCondition) {
is QueryCondition.CustomFieldNumberQuery -> R.string.value
is QueryCondition.CustomFieldAmountQuery -> R.string.amount
else -> this.filterSectionRow.resId
}
}
else -> this.resId
}
arrayListOf(
RowRepresentableEditDescriptor(valueAsString, hint, inputType = InputType.TYPE_CLASS_NUMBER)
)
}
else -> super.editingDescriptors(map)
}
}
}
open class FixedValueFilterItemRow(queryCondition: QueryCondition,
override var filterSectionRow: FilterSectionRow) : FilterItemRow {
override val rawCondition: QueryCondition = queryCondition
override val queryCondition: QueryCondition?
get() { return rawCondition }
override fun valueFormatted(context: Context): CharSequence? {
throw PAIllegalStateException("Not applicable for $rawCondition")
}
override val singleValue: Any?
get() { throw PAIllegalStateException("Not applicable for $rawCondition") }
}
abstract class ValueFilterItemRow<T: Comparable<T>>(queryCondition: QueryCondition.SingleValue<T>, filterSectionRow: FilterSectionRow): FixedValueFilterItemRow(queryCondition, filterSectionRow) {
private var valueCondition: QueryCondition.SingleValue<T> = queryCondition
var value: T? = null
override val queryCondition: QueryCondition?
get() {
value?.let {
valueCondition.singleValue = it
return valueCondition
}
return null
}
override fun valueFormatted(context: Context): CharSequence? {
(this.queryCondition as? QueryCondition.SingleValue<T>)?.let {
return it.labelForValue(it.singleValue, context)
}
return NULL_TEXT
}
override val singleValue: Any?
get() {
return this.value
}
override fun updateValue(fc: FilterCondition) {
val queryCondition = fc.queryCondition as QueryCondition.SingleValue<T>
this.value = queryCondition.singleValue
}
}
abstract class ValueListFilterItemRow<T: Comparable<T>>(queryCondition: QueryCondition.ListOfValues<T>, filterSectionRow: FilterSectionRow)
: FixedValueFilterItemRow(queryCondition, filterSectionRow) {
private var listCondition: QueryCondition.ListOfValues<T> = queryCondition
var list: MutableList<T> = mutableListOf()
private set
fun add(value: T) {
this.list.add(value)
}
override val queryCondition: QueryCondition?
get() {
return if (list.isNotEmpty()) {
listCondition.listOfValues = list
listCondition
} else {
null
}
}
override fun valueFormatted(context: Context): CharSequence? {
(this.queryCondition as? QueryCondition.ListOfValues<T>)?.let {
return it.labelForValue(this.list.first(), context)
}
return NULL_TEXT
}
override val singleValue: Any?
get() {
return this.list.firstOrNull()
}
override fun updateValue(fc: FilterCondition) {
val queryCondition = fc.queryCondition as QueryCondition.ListOfValues<T>
this.list = queryCondition.listOfValues
}
}
class DateFilterItemRow(queryCondition: QueryCondition.SingleDate, filterSectionRow: FilterSectionRow): ValueFilterItemRow<Date>(queryCondition, filterSectionRow)
class IntFilterItemRow(queryCondition: QueryCondition.SingleInt, filterSectionRow: FilterSectionRow): ValueFilterItemRow<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 StringValueListFilterItemRow(queryCondition: QueryCondition.ListOfString, filterSectionRow: FilterSectionRow): ValueListFilterItemRow<String>(queryCondition, filterSectionRow)

@ -8,6 +8,7 @@ import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.filter.mapFirstCondition import net.pokeranalytics.android.model.filter.mapFirstCondition
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.RowViewType
import java.util.*
sealed class FilterSectionRow(override val resId: Int?) : RowRepresentable { sealed class FilterSectionRow(override val resId: Int?) : RowRepresentable {
object CashOrTournament: FilterSectionRow(R.string.cash_or_tournament) object CashOrTournament: FilterSectionRow(R.string.cash_or_tournament)
@ -69,101 +70,118 @@ sealed class FilterSectionRow(override val resId: Int?) : RowRepresentable {
val allowMultiSelection: Boolean val allowMultiSelection: Boolean
get() = (this.selectionType == SelectionType.MULTIPLE) get() = (this.selectionType == SelectionType.MULTIPLE)
val filterElements: List<RowRepresentable> val filterItems: List<FilterItemRow>
get() { get() {
return this.queryConditions.map {
it.toRowWrapper(this@FilterSectionRow)
}
}
private val queryConditions: List<QueryCondition>
get() {
return when (this@FilterSectionRow) {
// General
CashOrTournament -> Criteria.SessionTypes.queryConditions.mapFirstCondition()
LiveOrOnline -> Criteria.BankrollTypes.queryConditions.mapFirstCondition()
Game -> Criteria.Games.queryConditions.mapFirstCondition()
LimitType -> Criteria.Limits.queryConditions.mapFirstCondition()
TableSize -> Criteria.TableSizes.queryConditions.mapFirstCondition()
// Date
DynamicDate -> arrayListOf(
QueryCondition.IsToday,
QueryCondition.WasYesterday,
QueryCondition.WasTodayAndYesterday,
QueryCondition.DuringThisWeek,
QueryCondition.DuringThisMonth,
QueryCondition.DuringThisYear
)
WeekdayOrWeekend -> arrayListOf(QueryCondition.IsWeekDay, QueryCondition.IsWeekEnd)
Year -> Criteria.Years.queryConditions.mapFirstCondition()
DayOfWeek -> Criteria.DaysOfWeek.queryConditions.mapFirstCondition()
MonthOfYear -> Criteria.MonthsOfYear.queryConditions.mapFirstCondition()
// Duration
SessionDuration -> QueryCondition.moreOrLess<QueryCondition.Duration>()
FixedDate -> arrayListOf(QueryCondition.StartedFromDate(Date()), QueryCondition.EndedToDate(Date())) // dummy constructor values
Duration -> arrayListOf(QueryCondition.PastDay(0)) // dummy constructor values
TimeFrameRange -> arrayListOf(QueryCondition.StartedFromTime(Date()), QueryCondition.EndedToTime(Date())) // dummy constructor values
val data = arrayListOf<RowRepresentable>().apply { // Sessions
this.addAll( //Sessions -> arrayListOf(QueryCondition.LastGame(), QueryCondition.LastSession())
when (this@FilterSectionRow) {
// Cash
// General Blind -> Criteria.Blinds.queryConditions.mapFirstCondition()
CashOrTournament -> Criteria.SessionTypes.queryConditions.mapFirstCondition()
LiveOrOnline -> Criteria.BankrollTypes.queryConditions.mapFirstCondition()
Game -> Criteria.Games.queryConditions.mapFirstCondition()
LimitType -> Criteria.Limits.queryConditions.mapFirstCondition()
TableSize -> Criteria.TableSizes.queryConditions.mapFirstCondition()
// Date
DynamicDate -> arrayListOf(
QueryCondition.IsToday,
QueryCondition.WasYesterday,
QueryCondition.WasTodayAndYesterday,
QueryCondition.DuringThisWeek,
QueryCondition.DuringThisMonth,
QueryCondition.DuringThisYear
)
FixedDate -> arrayListOf(QueryCondition.StartedFromDate(), QueryCondition.EndedToDate())
Duration -> arrayListOf(QueryCondition.PastDay())
WeekdayOrWeekend -> arrayListOf(QueryCondition.IsWeekDay, QueryCondition.IsWeekEnd)
Year -> Criteria.Years.queryConditions.mapFirstCondition()
DayOfWeek -> Criteria.DaysOfWeek.queryConditions.mapFirstCondition()
MonthOfYear -> Criteria.MonthsOfYear.queryConditions.mapFirstCondition()
// Duration
SessionDuration -> QueryCondition.moreOrLess<QueryCondition.Duration>()
TimeFrameRange -> arrayListOf(QueryCondition.StartedFromTime(), QueryCondition.EndedToTime())
// Sessions
//Sessions -> arrayListOf(QueryCondition.LastGame(), QueryCondition.LastSession())
// Cash
Blind -> Criteria.Blinds.queryConditions.mapFirstCondition()
// CashRebuyCount -> QueryCondition.moreOrLess<QueryCondition.Rebuy>() // CashRebuyCount -> QueryCondition.moreOrLess<QueryCondition.Rebuy>()
// Tournament // Tournament
TournamentType -> Criteria.TournamentTypes.queryConditions.mapFirstCondition() TournamentType -> Criteria.TournamentTypes.queryConditions.mapFirstCondition()
// CompletionPercentage -> arrayListOf() // CompletionPercentage -> arrayListOf()
TournamentFinalPosition -> QueryCondition.moreOrLess<QueryCondition.TournamentFinalPosition>() TournamentFinalPosition -> QueryCondition.moreOrLess<QueryCondition.TournamentFinalPosition>()
TournamentNumberOfPlayer -> QueryCondition.moreOrLess<QueryCondition.TournamentNumberOfPlayer>() TournamentNumberOfPlayer -> QueryCondition.moreOrLess<QueryCondition.TournamentNumberOfPlayer>()
TournamentEntryFee -> Criteria.TournamentFees.queryConditions.mapFirstCondition() TournamentEntryFee -> Criteria.TournamentFees.queryConditions.mapFirstCondition()
TournamentName -> Criteria.TournamentNames.queryConditions.mapFirstCondition() TournamentName -> Criteria.TournamentNames.queryConditions.mapFirstCondition()
TournamentFeature -> Criteria.TournamentFeatures.queryConditions.mapFirstCondition() TournamentFeature -> Criteria.TournamentFeatures.queryConditions.mapFirstCondition()
Location -> Criteria.Locations.queryConditions.mapFirstCondition() Location -> Criteria.Locations.queryConditions.mapFirstCondition()
Bankroll -> Criteria.Bankrolls.queryConditions.mapFirstCondition() Bankroll -> Criteria.Bankrolls.queryConditions.mapFirstCondition()
MultiTabling -> QueryCondition.moreOrLess<QueryCondition.NumberOfTable>() MultiTabling -> QueryCondition.moreOrLess<QueryCondition.NumberOfTable>()
//NumberOfPlayers -> QueryCondition.moreOrLess<QueryCondition.TournamentNumberOfPlayer>() //NumberOfPlayers -> QueryCondition.moreOrLess<QueryCondition.TournamentNumberOfPlayer>()
NumberOfRebuy -> QueryCondition.moreOrLess<QueryCondition.NumberOfRebuy>() NumberOfRebuy -> QueryCondition.moreOrLess<QueryCondition.NumberOfRebuy>()
// MultiPlayer -> arrayListOf() // MultiPlayer -> arrayListOf()
Value -> arrayListOf<QueryCondition>().apply { Value -> arrayListOf<QueryCondition>().apply {
addAll(QueryCondition.moreOrLess<QueryCondition.NetAmountWon>()) addAll(QueryCondition.moreOrLess<QueryCondition.NetAmountWon>())
addAll(QueryCondition.moreOrLess<QueryCondition.NetAmountLost>()) addAll(QueryCondition.moreOrLess<QueryCondition.NetAmountLost>())
} }
TransactionType -> Criteria.TransactionTypes.queryConditions.mapFirstCondition() TransactionType -> Criteria.TransactionTypes.queryConditions.mapFirstCondition()
is CustomField -> { is CustomField -> {
val cf = this@FilterSectionRow.customField val cf = this@FilterSectionRow.customField
if (cf.isListType) { when {
Criteria.ListCustomFields(cf.id).queryConditions.mapFirstCondition() cf.isListType -> {
} else if (cf.isAmountType) { Criteria.ListCustomFields(cf.id).queryConditions.mapFirstCondition()
QueryCondition.moreOrLess<QueryCondition.CustomFieldAmountQuery>().apply { }
this.forEach { cf.isAmountType -> {
it.customFieldId = cf.id QueryCondition.moreOrLess<QueryCondition.CustomFieldAmountQuery>().apply {
} this.forEach {
} it.customFieldId = cf.id
} else { }
QueryCondition.moreOrLess<QueryCondition.CustomFieldNumberQuery>().apply { }
this.forEach { }
it.customFieldId = cf.id else -> {
} QueryCondition.moreOrLess<QueryCondition.CustomFieldNumberQuery>().apply {
} this.forEach {
} it.customFieldId = cf.id
} }
else -> arrayListOf() }
}.apply {
this.forEach {
it.filterSectionRow = this@FilterSectionRow
} }
} }
) }
else -> arrayListOf()
} }
}
// Add the section row only if we have data for this section
if (data.isNotEmpty()) {
data.add(0, this@FilterSectionRow)
}
return data // val filterElements: List<RowRepresentable>
} // get() {
//
// val data = arrayListOf<RowRepresentable>().apply {
// this.addAll(
// filterItems.apply {
// this.forEach {
// it.filterSectionRow = this@FilterSectionRow
// }
// }
// )
// }
//
// // Add the section row only if we have data for this section
// if (data.isNotEmpty()) {
// data.add(0, this@FilterSectionRow)
// }
//
// return data
// }
private val selectionType: SelectionType private val selectionType: SelectionType
get() { get() {

@ -1,61 +1,37 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/mainLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:id="@+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<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.core.widget.NestedScrollView>
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar" android:id="@+id/appBar"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="128dp" android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> android:theme="@style/PokerAnalyticsTheme.Toolbar.Session"
app:layout_constraintEnd_toEndOf="parent"
<com.google.android.material.appbar.CollapsingToolbarLayout app:layout_constraintStart_toStartOf="parent"
android:id="@+id/collapsingToolbar" app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="?attr/actionBarSize"
app:collapsedTitleTextAppearance="@style/PokerAnalyticsTheme.Toolbar.CollapsedTitleAppearance" app:layout_constraintEnd_toEndOf="parent"
app:contentScrim="?attr/colorPrimary" app:layout_constraintStart_toStartOf="parent"
app:expandedTitleGravity="bottom" app:layout_constraintTop_toTopOf="parent"
app:expandedTitleMarginStart="72dp" app:title="@string/reports" />
app:expandedTitleTextAppearance="@style/PokerAnalyticsTheme.Toolbar.ExpandedTitleAppearance"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:title="Poker Analytics"
app:titleTextColor="@color/white" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> <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_toBottomOf="@+id/appBar" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,27 @@
package net.pokeranalytics.android
import org.junit.Assert
import org.junit.Test
class IntHolder(var value: Int)
class StringHolder(var value: String)
class InstantiationTest : RealmUnitTest() {
@Test
fun testIntInstance() {
Assert.assertEquals(0, 0)
val c = IntHolder::class.java
val constructor = c.declaredConstructors.first()
val type = constructor.parameterTypes.first()
when (type) {
Int::class.java -> {
// good
}
else -> Assert.fail()
}
}
}
Loading…
Cancel
Save