Adds ALL option to Calendar

blinds
Laurent 5 years ago
parent e663e55f1f
commit ef80ab83ee
  1. 132
      app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt
  2. 6
      app/src/main/res/layout-sw320dp/fragment_calendar.xml
  3. 34
      app/src/main/res/layout-sw400dp/fragment_calendar.xml
  4. 6
      app/src/main/res/layout/fragment_calendar.xml

@ -7,14 +7,17 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import io.realm.Realm import io.realm.Realm
import io.realm.RealmModel
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputedResults import net.pokeranalytics.android.calculus.ComputedResults
import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.databinding.FragmentCalendarBinding import net.pokeranalytics.android.databinding.FragmentCalendarBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.Criteria import net.pokeranalytics.android.model.Criteria
import net.pokeranalytics.android.model.combined import net.pokeranalytics.android.model.combined
import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.filter.QueryCondition
@ -40,7 +43,7 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
RowRepresentableDelegate, RealmAsyncListener { RowRepresentableDelegate, RealmAsyncListener {
enum class TimeFilter { enum class TimeFilter {
MONTH, YEAR ALL, MONTH, YEAR
} }
companion object { companion object {
@ -58,18 +61,16 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
private lateinit var calendarAdapter: RowRepresentableAdapter private lateinit var calendarAdapter: RowRepresentableAdapter
// override val coroutineContext: CoroutineContext
// get() = Dispatchers.Main
private var rows: ArrayList<CustomizableRowRepresentable> = ArrayList() private var rows: ArrayList<CustomizableRowRepresentable> = ArrayList()
private var allComputedResults: ComputedResults? = null
private var sortedMonthlyReports: SortedMap<Date, ComputedResults> = HashMap<Date, ComputedResults>().toSortedMap() private var sortedMonthlyReports: SortedMap<Date, ComputedResults> = HashMap<Date, ComputedResults>().toSortedMap()
private var sortedYearlyReports: SortedMap<Date, ComputedResults> = HashMap<Date, ComputedResults>().toSortedMap() private var sortedYearlyReports: SortedMap<Date, ComputedResults> = HashMap<Date, ComputedResults>().toSortedMap()
private var datesForRows: HashMap<CustomizableRowRepresentable, Date> = HashMap() private var datesForRows: HashMap<CustomizableRowRepresentable, Date> = HashMap()
private var sessionTypeCondition: QueryCondition? = null private var sessionTypeCondition: QueryCondition? = null
private var currentTimeFilter: TimeFilter = private var currentTimeFilter: TimeFilter = TimeFilter.MONTH
TimeFilter.MONTH
private var currentStat = Stat.NET_RESULT private var currentStat = Stat.NET_RESULT
private var _binding: FragmentCalendarBinding? = null private var _binding: FragmentCalendarBinding? = null
@ -123,10 +124,16 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
CalendarDetailsActivity.newInstance(requireContext(), it, sessionTypeCondition, date?.getDateYear()) CalendarDetailsActivity.newInstance(requireContext(), it, sessionTypeCondition, date?.getDateYear())
} }
} }
TimeFilter.ALL -> {
this.allComputedResults?.let {
CalendarDetailsActivity.newInstance(requireContext(), it, sessionTypeCondition, getString(
R.string.all))
} ?: throw PAIllegalStateException("all results required to display details but null")
}
} }
} }
// override val observedEntities: List<Class<out RealmModel>> = listOf(ComputableResult::class.java) override val observedEntities: List<Class<out RealmModel>> = listOf(ComputableResult::class.java)
// override fun entitiesChanged(clazz: Class<out RealmModel>, results: RealmResults<out RealmModel>) { // override fun entitiesChanged(clazz: Class<out RealmModel>, results: RealmResults<out RealmModel>) {
// launchAsyncStatComputation() // launchAsyncStatComputation()
@ -206,27 +213,33 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
} }
} }
binding.filterTimeAll?.setOnCheckedChangeListener { _, isChecked ->
selectTimeFilter(TimeFilter.ALL, isChecked)
}
// Manage time queryWith // Manage time queryWith
binding.filterTimeMonth.setOnCheckedChangeListener { _, isChecked -> binding.filterTimeMonth.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) { selectTimeFilter(TimeFilter.MONTH, isChecked)
currentTimeFilter = // if (isChecked) {
TimeFilter.MONTH // currentTimeFilter =
binding.filterTimeYear.isChecked = false // TimeFilter.MONTH
displayData() // binding.filterTimeYear.isChecked = false
} else if (currentTimeFilter == TimeFilter.MONTH) { // displayData()
binding.filterTimeMonth.isChecked = true // } else if (currentTimeFilter == TimeFilter.MONTH) {
} // binding.filterTimeMonth.isChecked = true
// }
} }
binding.filterTimeYear.setOnCheckedChangeListener { _, isChecked -> binding.filterTimeYear.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) { selectTimeFilter(TimeFilter.YEAR, isChecked)
currentTimeFilter = // if (isChecked) {
TimeFilter.YEAR // currentTimeFilter =
binding.filterTimeMonth.isChecked = false // TimeFilter.YEAR
displayData() // binding.filterTimeMonth.isChecked = false
} else if (currentTimeFilter == TimeFilter.YEAR) { // displayData()
binding.filterTimeYear.isChecked = true // } else if (currentTimeFilter == TimeFilter.YEAR) {
} // binding.filterTimeYear.isChecked = true
// }
} }
val viewManager = LinearLayoutManager(requireContext()) val viewManager = LinearLayoutManager(requireContext())
@ -240,6 +253,29 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
} }
} }
private fun selectTimeFilter(timeFilter: TimeFilter, isChecked: Boolean) {
if (isChecked) {
currentTimeFilter = timeFilter
TimeFilter.values().forEach { tf ->
if (tf != timeFilter) {
when (tf) {
TimeFilter.ALL -> binding.filterTimeAll?.isChecked = false
TimeFilter.MONTH -> binding.filterTimeMonth.isChecked = false
TimeFilter.YEAR -> binding.filterTimeYear.isChecked = false
}
}
}
displayData()
} else if (currentTimeFilter == timeFilter) {
when (timeFilter) {
TimeFilter.ALL -> binding.filterTimeAll?.isChecked = true
TimeFilter.MONTH -> binding.filterTimeMonth.isChecked = true
TimeFilter.YEAR -> binding.filterTimeYear.isChecked = true
}
}
}
/** /**
* Asynchronously Launch stat computation * Asynchronously Launch stat computation
*/ */
@ -270,15 +306,19 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
val startDate = Date() val startDate = Date()
val monthlyReports: HashMap<Date, ComputedResults> = HashMap()
val yearlyReports: HashMap<Date, ComputedResults> = HashMap()
val requiredStats: List<Stat> = val requiredStats: List<Stat> =
listOf(Stat.LOCATIONS_PLAYED, Stat.LONGEST_STREAKS, Stat.DAYS_PLAYED, Stat.STANDARD_DEVIATION_HOURLY) listOf(Stat.LOCATIONS_PLAYED, Stat.LONGEST_STREAKS, Stat.DAYS_PLAYED, Stat.STANDARD_DEVIATION_HOURLY)
// Compute data per AnyYear and AnyMonthOfYear // All
val allOptions = Calculator.Options(
progressValues = Calculator.Options.ProgressValues.STANDARD,
stats = requiredStats,
)
val allReport = Calculator.computeStats(realm, options = allOptions)
this.allComputedResults = allReport.results.first()
// println(">>>> ${Criteria.MonthsOfYear.queryConditions.map { it.id }}") // Month
val monthlyReports: HashMap<Date, ComputedResults> = HashMap()
val monthlyQueries = when (sessionTypeCondition) { val monthlyQueries = when (sessionTypeCondition) {
QueryCondition.IsCash -> listOf(Criteria.AllMonthsUpToNow, Criteria.Cash).combined() QueryCondition.IsCash -> listOf(Criteria.AllMonthsUpToNow, Criteria.Cash).combined()
@ -313,7 +353,9 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
calendar.time = Date().startOfYear() calendar.time = Date().startOfYear()
// Compute data per AnyYear // Year
val yearlyReports: HashMap<Date, ComputedResults> = HashMap()
val yearConditions = when (sessionTypeCondition) { val yearConditions = when (sessionTypeCondition) {
QueryCondition.IsCash -> listOf(Criteria.Years, Criteria.Cash).combined() QueryCondition.IsCash -> listOf(Criteria.Years, Criteria.Cash).combined()
QueryCondition.IsTournament -> listOf(Criteria.Years, Criteria.Tournament).combined() QueryCondition.IsTournament -> listOf(Criteria.Years, Criteria.Tournament).combined()
@ -370,9 +412,24 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
datesForRows.clear() datesForRows.clear()
rows.clear() rows.clear()
when (currentTimeFilter) { // Create all rows
when (this.currentTimeFilter) {
// All
TimeFilter.ALL -> {
this.allComputedResults?.computedStat(currentStat)?.let { computedStat ->
val row = CustomizableRowRepresentable(
customViewType = RowViewType.TITLE_VALUE_ARROW,
title = getString(R.string.all),
valueTextFormat = computedStat.textFormat,
isSelectable = true
)
rows.add(row)
}
}
// Create monthly reports // MONTH
TimeFilter.MONTH -> { TimeFilter.MONTH -> {
val years: ArrayList<String> = ArrayList() val years: ArrayList<String> = ArrayList()
sortedMonthlyReports.keys.forEach { date -> sortedMonthlyReports.keys.forEach { date ->
@ -401,7 +458,7 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
} }
} }
// Create yearly reports // YEAR
TimeFilter.YEAR -> { TimeFilter.YEAR -> {
sortedYearlyReports.keys.forEach { date -> sortedYearlyReports.keys.forEach { date ->
sortedYearlyReports[date]?.computedStat(currentStat)?.let { computedStat -> sortedYearlyReports[date]?.computedStat(currentStat)?.let { computedStat ->
@ -430,15 +487,8 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
} }
override fun asyncListenedEntityChange(realm: Realm) { override fun asyncListenedEntityChange(realm: Realm) {
launchAsyncStatComputation() launchAsyncStatComputation()
// Timber.d("asyncListenedEntityChange")
// launchStatComputation(realm)
//
// activity?.runOnUiThread {
// displayData()
// }
} }
} }

@ -36,6 +36,12 @@
app:singleSelection="false" app:singleSelection="false"
app:chipSpacing="6dp"> app:chipSpacing="6dp">
<com.google.android.material.chip.Chip
android:id="@+id/filterTimeAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/all"/>
<com.google.android.material.chip.Chip <com.google.android.material.chip.Chip
android:id="@+id/filterTimeMonth" android:id="@+id/filterTimeMonth"
android:layout_width="wrap_content" android:layout_width="wrap_content"

@ -26,61 +26,63 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:orientation="horizontal" android:layout_margin="8dp"
android:padding="8dp"> android:orientation="vertical">
<com.google.android.material.chip.ChipGroup <com.google.android.material.chip.ChipGroup
android:id="@+id/filtersTime" android:id="@+id/filtersTime"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:chipSpacing="8dp" app:singleSelection="false"
app:singleSelection="false"> app:chipSpacing="6dp">
<com.google.android.material.chip.Chip
android:id="@+id/filterTimeAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/all"/>
<com.google.android.material.chip.Chip <com.google.android.material.chip.Chip
android:id="@+id/filterTimeMonth" android:id="@+id/filterTimeMonth"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="true" android:checked="true"
android:text="@string/month" /> android:text="@string/month"/>
<com.google.android.material.chip.Chip <com.google.android.material.chip.Chip
android:id="@+id/filterTimeYear" android:id="@+id/filterTimeYear"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/year" /> android:text="@string/year"/>
</com.google.android.material.chip.ChipGroup> </com.google.android.material.chip.ChipGroup>
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<com.google.android.material.chip.ChipGroup <com.google.android.material.chip.ChipGroup
android:id="@+id/filtersSession" android:id="@+id/filtersSession"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:chipSpacing="6dp" android:layout_margin="8dp"
app:singleSelection="false"> app:singleSelection="false"
app:chipSpacing="6dp">
<com.google.android.material.chip.Chip <com.google.android.material.chip.Chip
android:id="@+id/filterSessionAll" android:id="@+id/filterSessionAll"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="true" android:checked="true"
android:text="@string/all" /> android:text="@string/all"/>
<com.google.android.material.chip.Chip <com.google.android.material.chip.Chip
android:id="@+id/filterSessionCash" android:id="@+id/filterSessionCash"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/cash_game" /> android:text="@string/cash_game"/>
<com.google.android.material.chip.Chip <com.google.android.material.chip.Chip
android:id="@+id/filterSessionTournament" android:id="@+id/filterSessionTournament"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/tournament" /> android:text="@string/tournament"/>
</com.google.android.material.chip.ChipGroup> </com.google.android.material.chip.ChipGroup>

@ -37,6 +37,12 @@
app:singleSelection="false" app:singleSelection="false"
app:chipSpacing="8dp"> app:chipSpacing="8dp">
<com.google.android.material.chip.Chip
android:id="@+id/filterTimeAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/all"/>
<com.google.android.material.chip.Chip <com.google.android.material.chip.Chip
android:id="@+id/filterTimeMonth" android:id="@+id/filterTimeMonth"
android:layout_width="wrap_content" android:layout_width="wrap_content"

Loading…
Cancel
Save