Compare commits

...

17 Commits
master ... kmm

  1. 6
      app/build.gradle
  2. 84
      app/src/main/java/net/pokeranalytics/android/calcul/ComputedResultsExtensions.kt
  3. 64
      app/src/main/java/net/pokeranalytics/android/calcul/ReportExtensions.kt
  4. 7
      app/src/main/java/net/pokeranalytics/android/calculus/AggregationType.kt
  5. 90
      app/src/main/java/net/pokeranalytics/android/calculus/ComputableGroup.kt
  6. 239
      app/src/main/java/net/pokeranalytics/android/calculus/Report.kt
  7. 10
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  8. 9
      app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt
  9. 48
      app/src/main/java/net/pokeranalytics/android/ui/activity/ColorPickerActivity.kt
  10. 12
      app/src/main/java/net/pokeranalytics/android/ui/activity/GDPRActivity.kt
  11. 17
      app/src/main/java/net/pokeranalytics/android/ui/activity/GraphActivity.kt
  12. 15
      app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt
  13. 5
      app/src/main/java/net/pokeranalytics/android/ui/adapter/ComparisonChartPagerAdapter.kt
  14. 7
      app/src/main/java/net/pokeranalytics/android/ui/adapter/ReportPagerAdapter.kt
  15. 4
      app/src/main/java/net/pokeranalytics/android/ui/extensions/UIExtensions.kt
  16. 17
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ComparisonChartFragment.kt
  17. 20
      app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt
  18. 55
      app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt
  19. 49
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt
  20. 33
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportCreationFragment.kt
  21. 24
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt
  22. 28
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt
  23. 21
      app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt
  24. 55
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt
  25. 27
      app/src/main/java/net/pokeranalytics/android/ui/fragment/Top10Fragment.kt
  26. 33
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/FilterableFragment.kt
  27. 22
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/LoaderDialogFragment.kt
  28. 27
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/ScreenSlidePageFragment.kt
  29. 59
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt
  30. 26
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetEditTextFragment.kt
  31. 22
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetEditTextMultiLinesFragment.kt
  32. 24
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt
  33. 22
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListFragment.kt
  34. 23
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListGameFragment.kt
  35. 17
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetMultiSelectionFragment.kt
  36. 23
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetNumericTextFragment.kt
  37. 24
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetStaticListFragment.kt
  38. 29
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetSumFragment.kt
  39. 24
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetTableSizeGridFragment.kt
  40. 25
      app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComparisonReportFragment.kt
  41. 51
      app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComposableTableReportFragment.kt
  42. 48
      app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ProgressReportFragment.kt
  43. 24
      app/src/main/java/net/pokeranalytics/android/ui/fragment/report/TableReportFragment.kt
  44. 7
      app/src/main/java/net/pokeranalytics/android/ui/graph/GraphExtensions.kt
  45. 16
      app/src/main/java/net/pokeranalytics/android/ui/graph/GraphUnderlyingEntry.kt
  46. 18
      app/src/main/java/net/pokeranalytics/android/ui/modules/bankroll/BankrollDetailsFragment.kt
  47. 18
      app/src/main/java/net/pokeranalytics/android/ui/modules/bankroll/BankrollFragment.kt
  48. 48
      app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarDetailsFragment.kt
  49. 70
      app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt
  50. 41
      app/src/main/java/net/pokeranalytics/android/ui/modules/data/CustomFieldDataFragment.kt
  51. 16
      app/src/main/java/net/pokeranalytics/android/ui/modules/data/EditableDataFragment.kt
  52. 17
      app/src/main/java/net/pokeranalytics/android/ui/modules/data/PlayerDataFragment.kt
  53. 21
      app/src/main/java/net/pokeranalytics/android/ui/modules/datalist/DataListFragment.kt
  54. 51
      app/src/main/java/net/pokeranalytics/android/ui/modules/feed/FeedFragment.kt
  55. 10
      app/src/main/java/net/pokeranalytics/android/ui/modules/feed/FeedSessionRowRepresentableAdapter.kt
  56. 7
      app/src/main/java/net/pokeranalytics/android/ui/modules/feed/FeedTransactionRowRepresentableAdapter.kt
  57. 26
      app/src/main/java/net/pokeranalytics/android/ui/modules/feed/NewDataMenuActivity.kt
  58. 22
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterDetailsFragment.kt
  59. 34
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersFragment.kt
  60. 3
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersListFragment.kt
  61. 261
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/editor/EditorAdapter.kt
  62. 42
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/editor/EditorFragment.kt
  63. 45
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerFragment.kt
  64. 20
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/KeyboardActionView.kt
  65. 22
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/KeyboardAmountView.kt
  66. 20
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/KeyboardCardView.kt
  67. 20
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/RowHandHistoryViewHolder.kt
  68. 43
      app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt
  69. 29
      app/src/main/java/net/pokeranalytics/android/ui/view/LegendView.kt
  70. 19
      app/src/main/java/net/pokeranalytics/android/ui/view/MultiLineLegendView.kt
  71. 48
      app/src/main/java/net/pokeranalytics/android/ui/view/PlayerImageView.kt
  72. 16
      app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt
  73. 99
      app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt
  74. 12
      app/src/main/java/net/pokeranalytics/android/ui/view/TransactionRowView.kt
  75. 6
      app/src/main/java/net/pokeranalytics/android/ui/viewmodel/GraphViewModel.kt
  76. 3
      app/src/main/java/net/pokeranalytics/android/ui/viewmodel/ReportHolder.kt
  77. 5
      app/src/main/java/net/pokeranalytics/android/ui/viewmodel/ReportViewModel.kt
  78. 3
      app/src/main/res/layout/row_session_view.xml
  79. 4
      build.gradle
  80. 2
      gradle.properties
  81. 4
      gradle/wrapper/gradle-wrapper.properties
  82. 1
      settings.gradle
  83. 42
      shared/build.gradle.kts
  84. 2
      shared/src/androidMain/AndroidManifest.xml
  85. 5
      shared/src/androidMain/kotlin/net/pokeranalytics/shared/Platform.kt
  86. 12
      shared/src/androidTest/kotlin/net/pokeranalytics/shared/androidTest.kt
  87. 7
      shared/src/commonMain/kotlin/net/pokeranalytics/shared/Greeting.kt
  88. 5
      shared/src/commonMain/kotlin/net/pokeranalytics/shared/Platform.kt
  89. 8
      shared/src/iosMain/kotlin/net/pokeranalytics/shared/Platform.kt
  90. 12
      shared/src/iosTest/kotlin/net/pokeranalytics/shared/iosTest.kt

@ -1,6 +1,6 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
//apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'realm-android'
// Crashlytics
@ -93,6 +93,10 @@ android {
}
}
buildFeatures {
viewBinding true
}
}
dependencies {

@ -0,0 +1,84 @@
package net.pokeranalytics.android.calcul
import android.content.Context
import com.github.mikephil.charting.data.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedResults
import net.pokeranalytics.android.calculus.Point
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.ui.graph.DataSetFactory
import kotlin.math.abs
// MPAndroidChart
fun ComputedResults.defaultStatEntries(stat: Stat, context: Context): DataSet<out Entry> {
return when (stat) {
Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_GAMES, Stat.HOURLY_DURATION -> this.barEntries(stat, context = context)
Stat.STANDARD_DEVIATION -> this.distributionEntries(stat, context)
else -> this.singleLineEntries(stat, context)
}
}
fun ComputedResults.singleLineEntries(stat: Stat, context: Context): LineDataSet {
val entries = mutableListOf<Entry>()
this.evolutionValues[stat]?.let { points ->
points.forEachIndexed { index, p ->
entries.add(Entry(index.toFloat(), p.y.toFloat(), p.data))
}
}
return DataSetFactory.lineDataSetInstance(entries, this.group.query.getName(context), context)
}
fun ComputedResults.durationEntries(stat: Stat, context: Context): LineDataSet {
val entries = mutableListOf<Entry>()
this.evolutionValues[stat]?.let { points ->
points.forEach { p ->
entries.add(Entry(p.x.toFloat(), p.y.toFloat(), p.data))
}
}
return DataSetFactory.lineDataSetInstance(entries, stat.name, context)
}
private fun ComputedResults.barEntries(stat: Stat, context: Context): BarDataSet {
val entries = mutableListOf<BarEntry>()
this.evolutionValues[stat]?.let { points ->
points.forEach { p ->
entries.add(BarEntry(p.x.toFloat(), p.y.toFloat(), p.data))
}
}
return DataSetFactory.barDataSetInstance(entries, stat.name, context)
}
private fun ComputedResults.distributionEntries(stat: Stat, context: Context): BarDataSet {
val colors = mutableListOf<Int>()
val entries = mutableListOf<BarEntry>()
this.evolutionValues[stat]?.let { points ->
val negative = mutableListOf<Point>()
val positive = mutableListOf<Point>()
points.sortByDescending { it.y }
points.forEach {
if (it.y < 0) {
negative.add(it)
} else {
positive.add(it)
}
}
negative.forEachIndexed { index, p ->
entries.add(BarEntry(index.toFloat(), abs(p.y.toFloat()), p.data))
colors.add(context.getColor(R.color.red))
}
positive.forEachIndexed { index, p ->
val x = negative.size + index.toFloat()
entries.add(BarEntry(x, p.y.toFloat(), p.data))
colors.add(context.getColor(R.color.green))
}
}
return DataSetFactory.barDataSetInstance(entries, stat.name, context, colors)
}

@ -0,0 +1,64 @@
package net.pokeranalytics.android.calcul
import android.content.Context
import com.github.mikephil.charting.data.BarDataSet
import com.github.mikephil.charting.data.BarEntry
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineDataSet
import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.ui.graph.DataSetFactory
import net.pokeranalytics.android.util.ColorUtils
/**
* Returns the list of entries corresponding to the provided [stat]
* One value will be returned by result
*/
fun Report.lineEntries(stat: Stat? = null, context: Context): LineDataSet {
val entries = mutableListOf<Entry>()
val statToUse = stat ?: this.options.stats.firstOrNull()
val statName = statToUse?.name ?: ""
statToUse?.let {
this.results.forEachIndexed { index, results ->
results.computedStat(it)?.progressValue?.let { progressValue ->
entries.add(Entry(index.toFloat(), progressValue.toFloat(), results))
}
}
}
return DataSetFactory.lineDataSetInstance(entries, statName, context)
}
fun Report.barEntries(stat: Stat? = null, context: Context): BarDataSet {
val entries = mutableListOf<BarEntry>()
val statToUse = stat ?: options.stats.firstOrNull()
statToUse?.let {
this.results.forEachIndexed { index, results ->
val cs = results.computedStat(it)
cs?.let { computedStat ->
val barEntry = BarEntry(index.toFloat(), computedStat.value.toFloat(), results)
entries.add(barEntry)
}
}
}
val label = statToUse?.name ?: ""
return DataSetFactory.barDataSetInstance(entries, label, context)
}
fun Report.multiLineEntries(context: Context): List<LineDataSet> {
val dataSets = mutableListOf<LineDataSet>()
options.stats.forEach { stat ->
this.results.forEachIndexed { index, result ->
val ds = result.singleLineEntries(stat, context)
ds.color = ColorUtils.almostRandomColor(index, context)
dataSets.add(ds)
}
}
return dataSets
}

@ -2,7 +2,12 @@ package net.pokeranalytics.android.calculus
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.Criteria
import net.pokeranalytics.android.ui.graph.AxisFormatting
enum class AxisFormatting {
DEFAULT,
X_DURATION,
Y_DURATION,
}
enum class AggregationType {
SESSION,

@ -0,0 +1,90 @@
package net.pokeranalytics.android.calculus
import io.realm.Realm
import io.realm.RealmResults
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.realm.ComputableResult
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.model.realm.SessionSet
/**
* A sessionGroup of computable items identified by a name
*/
class ComputableGroup(var query: Query, var stats: List<Stat>? = null) {
/**
* A subgroup used to compute stat variation
*/
var comparedGroup: ComputableGroup? = null
/**
* The computed statIds of the comparable sessionGroup
*/
var comparedComputedResults: ComputedResults? = null
/**
* A list of _conditions to get
*/
val conditions: List<QueryCondition>
get() {
return this.query.conditions
}
/**
* The list of endedSessions to compute
*/
private var _computables: RealmResults<ComputableResult>? = null
/**
* Retrieves the computables on the relative [realm] filtered with the provided [conditions]
*/
fun computables(realm: Realm, sorted: Boolean = false): RealmResults<ComputableResult> {
// if computables exists and is valid (previous realm not closed)
this._computables?.let {
if (it.isValid) {
return it
}
}
val sortedField = if (sorted) "session.startDate" else null
val computables = Filter.queryOn<ComputableResult>(realm, this.query, sortedField)
this._computables = computables
return computables
}
/**
* The list of sets to compute
*/
private var _sessionSets: RealmResults<SessionSet>? = null
/**
* Retrieves the session sets on the relative [realm] filtered with the provided [conditions]
*/
fun sessionSets(realm: Realm, sorted: Boolean = false): RealmResults<SessionSet> {
// if computables exists and is valid (previous realm not closed)
this._sessionSets?.let {
if (it.isValid) {
return it
}
}
val sortedField = if (sorted) SessionSet.Field.START_DATE.identifier else null
val sets = Filter.queryOn<SessionSet>(realm, this.query, sortedField)
this._sessionSets = sets
return sets
}
fun cleanup() {
this._computables = null
this._sessionSets = null
}
val isEmpty: Boolean
get() {
return this._computables?.isEmpty() ?: true
}
}

@ -1,25 +1,14 @@
package net.pokeranalytics.android.calculus
import android.content.Context
import com.github.mikephil.charting.data.*
import io.realm.Realm
import io.realm.RealmResults
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.GraphIdentifiableEntry
import net.pokeranalytics.android.model.realm.ComputableResult
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.model.realm.SessionSet
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.graph.DataSetFactory
import net.pokeranalytics.android.ui.graph.Graph
import net.pokeranalytics.android.ui.graph.GraphUnderlyingEntry
import net.pokeranalytics.android.ui.view.DefaultLegendValues
import net.pokeranalytics.android.ui.view.LegendContent
import net.pokeranalytics.android.util.ColorUtils
import net.pokeranalytics.android.util.TextFormat
import kotlin.math.abs
/**
* The class returned after performing calculation in the Calculator object
@ -43,138 +32,11 @@ class Report(var options: Calculator.Options) {
this._results.add(result)
}
/**
* Returns the list of entries corresponding to the provided [stat]
* One value will be returned by result
*/
fun lineEntries(stat: Stat? = null, context: Context): LineDataSet {
val entries = mutableListOf<Entry>()
val statToUse = stat ?: options.stats.firstOrNull()
val statName = statToUse?.name ?: ""
statToUse?.let {
this._results.forEachIndexed { index, results ->
results.computedStat(it)?.progressValue?.let { progressValue ->
entries.add(Entry(index.toFloat(), progressValue.toFloat(), results))
}
}
}
return DataSetFactory.lineDataSetInstance(entries, statName, context)
}
fun barEntries(stat: Stat? = null, context: Context): BarDataSet {
val entries = mutableListOf<BarEntry>()
val statToUse = stat ?: options.stats.firstOrNull()
statToUse?.let {
this._results.forEachIndexed { index, results ->
val cs = results.computedStat(it)
cs?.let { computedStat ->
val barEntry = BarEntry(index.toFloat(), computedStat.value.toFloat(), results)
entries.add(barEntry)
}
}
}
val label = statToUse?.name ?: ""
return DataSetFactory.barDataSetInstance(entries, label, context)
}
fun multiLineEntries(context: Context): List<LineDataSet> {
val dataSets = mutableListOf<LineDataSet>()
options.stats.forEach { stat ->
this._results.forEachIndexed { index, result ->
val ds = result.singleLineEntries(stat, context)
ds.color = ColorUtils.almostRandomColor(index, context)
dataSets.add(ds)
}
}
return dataSets
}
}
/**
* A sessionGroup of computable items identified by a name
*/
class ComputableGroup(var query: Query, var stats: List<Stat>? = null) {
/**
* A subgroup used to compute stat variation
*/
var comparedGroup: ComputableGroup? = null
/**
* The computed statIds of the comparable sessionGroup
*/
var comparedComputedResults: ComputedResults? = null
/**
* A list of _conditions to get
*/
val conditions: List<QueryCondition>
get() {
return this.query.conditions
}
/**
* The list of endedSessions to compute
*/
private var _computables: RealmResults<ComputableResult>? = null
/**
* Retrieves the computables on the relative [realm] filtered with the provided [conditions]
*/
fun computables(realm: Realm, sorted: Boolean = false): RealmResults<ComputableResult> {
// if computables exists and is valid (previous realm not closed)
this._computables?.let {
if (it.isValid) {
return it
}
}
val sortedField = if (sorted) "session.startDate" else null
val computables = Filter.queryOn<ComputableResult>(realm, this.query, sortedField)
this._computables = computables
return computables
}
/**
* The list of sets to compute
*/
private var _sessionSets: RealmResults<SessionSet>? = null
/**
* Retrieves the session sets on the relative [realm] filtered with the provided [conditions]
*/
fun sessionSets(realm: Realm, sorted: Boolean = false): RealmResults<SessionSet> {
// if computables exists and is valid (previous realm not closed)
this._sessionSets?.let {
if (it.isValid) {
return it
}
}
val sortedField = if (sorted) SessionSet.Field.START_DATE.identifier else null
val sets = Filter.queryOn<SessionSet>(realm, this.query, sortedField)
this._sessionSets = sets
return sets
}
fun cleanup() {
this._computables = null
this._sessionSets = null
}
val isEmpty: Boolean
get() {
return this._computables?.isEmpty() ?: true
}
class Point(val x: Double, val y: Double, val data: Any) {
constructor(y: Double, data: Any) : this(0.0, y, data)
}
class ComputedResults(group: ComputableGroup,
@ -196,6 +58,10 @@ class ComputedResults(group: ComputableGroup,
private val allStats: Collection<ComputedStat>
get() { return this._computedStats.values }
val evolutionValues: Map<Stat, MutableList<Point>>
get() {
return this._evolutionValues
}
/**
* Adds a value to the evolution values
@ -355,79 +221,6 @@ class ComputedResults(group: ComputableGroup,
this.consolidateProgressStats()
}
// MPAndroidChart
fun defaultStatEntries(stat: Stat, context: Context): DataSet<out Entry> {
return when (stat) {
Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_GAMES, Stat.HOURLY_DURATION -> this.barEntries(stat, context = context)
Stat.STANDARD_DEVIATION -> this.distributionEntries(stat, context)
else -> this.singleLineEntries(stat, context)
}
}
fun singleLineEntries(stat: Stat, context: Context): LineDataSet {
val entries = mutableListOf<Entry>()
this._evolutionValues[stat]?.let { points ->
points.forEachIndexed { index, p ->
entries.add(Entry(index.toFloat(), p.y.toFloat(), p.data))
}
}
return DataSetFactory.lineDataSetInstance(entries, this.group.query.getName(context), context)
}
fun durationEntries(stat: Stat, context: Context): LineDataSet {
val entries = mutableListOf<Entry>()
this._evolutionValues[stat]?.let { points ->
points.forEach { p ->
entries.add(Entry(p.x.toFloat(), p.y.toFloat(), p.data))
}
}
return DataSetFactory.lineDataSetInstance(entries, stat.name, context)
}
private fun barEntries(stat: Stat, context: Context): BarDataSet {
val entries = mutableListOf<BarEntry>()
this._evolutionValues[stat]?.let { points ->
points.forEach { p ->
entries.add(BarEntry(p.x.toFloat(), p.y.toFloat(), p.data))
}
}
return DataSetFactory.barDataSetInstance(entries, stat.name, context)
}
private fun distributionEntries(stat: Stat, context: Context): BarDataSet {
val colors = mutableListOf<Int>()
val entries = mutableListOf<BarEntry>()
this._evolutionValues[stat]?.let { points ->
val negative = mutableListOf<Point>()
val positive = mutableListOf<Point>()
points.sortByDescending { it.y }
points.forEach {
if (it.y < 0) {
negative.add(it)
} else {
positive.add(it)
}
}
negative.forEachIndexed { index, p ->
entries.add(BarEntry(index.toFloat(), abs(p.y.toFloat()), p.data))
colors.add(context.getColor(R.color.red))
}
positive.forEachIndexed { index, p ->
val x = negative.size + index.toFloat()
entries.add(BarEntry(x, p.y.toFloat(), p.data))
colors.add(context.getColor(R.color.green))
}
}
return DataSetFactory.barDataSetInstance(entries, stat.name, context, colors)
}
val isEmpty: Boolean
get() {
return this.group.isEmpty
@ -449,18 +242,18 @@ class ComputedResults(group: ComputableGroup,
override fun legendValues(
stat: Stat,
entry: Entry,
style: GraphFragment.Style,
total: Double,
style: Graph.Style,
groupName: String,
context: Context
): LegendContent {
when (style) {
GraphFragment.Style.BAR -> {
Graph.Style.BAR -> {
return when (stat) {
Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_GAMES, Stat.WIN_RATIO -> {
val totalStatValue = stat.textFormat(entry.y.toDouble(), currency = null)
val totalStatValue = stat.textFormat(total, currency = null)
DefaultLegendValues(this.entryTitle(context), totalStatValue)
}
else -> {
@ -474,12 +267,12 @@ class ComputedResults(group: ComputableGroup,
return when (stat) {
Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_GAMES, Stat.WIN_RATIO -> {
val totalStatValue = stat.textFormat(entry.y.toDouble(), currency = null)
val totalStatValue = stat.textFormat(total, currency = null)
DefaultLegendValues(this.entryTitle(context), totalStatValue)
}
else -> {
val entryValue = this.formattedValue(stat)
val totalStatValue = stat.textFormat(entry.y.toDouble(), currency = null)
val totalStatValue = stat.textFormat(total, currency = null)
DefaultLegendValues(this.entryTitle(context), entryValue, totalStatValue)
}
}
@ -489,9 +282,3 @@ class ComputedResults(group: ComputableGroup,
}
}
class Point(val x: Double, val y: Double, val data: Any) {
constructor(y: Double, data: Any) : this(0.0, y, data)
}

@ -1,7 +1,6 @@
package net.pokeranalytics.android.model.realm
import android.content.Context
import com.github.mikephil.charting.data.Entry
import io.realm.Realm
import io.realm.RealmList
import io.realm.RealmObject
@ -31,6 +30,7 @@ import net.pokeranalytics.android.model.utils.CrashLogging
import net.pokeranalytics.android.model.utils.SessionSetManager
import net.pokeranalytics.android.ui.adapter.UnmanagedRowRepresentableException
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.graph.Graph
import net.pokeranalytics.android.ui.view.*
import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow
import net.pokeranalytics.android.util.NULL_TEXT
@ -896,14 +896,14 @@ open class Session : RealmObject(), Savable, Editable, RowRepresentable, Timed,
override fun legendValues(
stat: Stat,
entry: Entry,
style: GraphFragment.Style,
total: Double,
style: Graph.Style,
groupName: String,
context: Context
): LegendContent {
when (style) {
GraphFragment.Style.MULTILINE -> {
Graph.Style.MULTILINE -> {
val secondTitle = stat.localizedTitle(context)
val entryValue = this.formattedValue(stat)
@ -929,7 +929,7 @@ open class Session : RealmObject(), Savable, Editable, RowRepresentable, Timed,
DefaultLegendValues(this.entryTitle(context), left, right)
}
else -> {
super<Timed>.legendValues(stat, entry, style, groupName, context)
super<Timed>.legendValues(stat, total, style, groupName, context)
}
}
}

@ -1,7 +1,6 @@
package net.pokeranalytics.android.model.realm
import android.content.Context
import com.github.mikephil.charting.data.Entry
import io.realm.Realm
import io.realm.RealmObject
import io.realm.annotations.Ignore
@ -12,7 +11,7 @@ import net.pokeranalytics.android.model.filter.Filterable
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.*
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.graph.Graph
import net.pokeranalytics.android.ui.view.DefaultLegendValues
import net.pokeranalytics.android.ui.view.LegendContent
import net.pokeranalytics.android.ui.view.RowRepresentable
@ -163,14 +162,14 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo
override fun legendValues(
stat: Stat,
entry: Entry,
style: GraphFragment.Style,
total: Double,
style: Graph.Style,
groupName: String,
context: Context
): LegendContent {
val entryValue = this.formattedValue(stat)
val totalStatValue = stat.textFormat(entry.y.toDouble(), currency = null)
val totalStatValue = stat.textFormat(total, currency = null)
val leftName = context.getString(R.string.amount)
return DefaultLegendValues(this.entryTitle(context), entryValue, totalStatValue, leftName = leftName)
}

@ -8,8 +8,8 @@ import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.activity_color_picker.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.ActivityColorPickerBinding
import net.pokeranalytics.android.ui.activity.components.BaseActivity
class ColorPickerActivity : BaseActivity() {
@ -33,15 +33,17 @@ class ColorPickerActivity : BaseActivity() {
}
override fun onCreate(savedInstanceState: Bundle?) {
private lateinit var binding: ActivityColorPickerBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { // used to fix Oreo crash
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
setContentView(R.layout.activity_color_picker)
binding = ActivityColorPickerBinding.inflate(layoutInflater)
setContentView(binding.root)
this.title = getString(R.string.select_a_color)
initUI()
}
@ -49,29 +51,29 @@ class ColorPickerActivity : BaseActivity() {
* Init UI
*/
private fun initUI() {
color1.setOnClickListener { manageSelectedColor(it) }
color2.setOnClickListener { manageSelectedColor(it) }
color3.setOnClickListener { manageSelectedColor(it) }
color4.setOnClickListener { manageSelectedColor(it) }
color5.setOnClickListener { manageSelectedColor(it) }
color6.setOnClickListener { manageSelectedColor(it) }
color7.setOnClickListener { manageSelectedColor(it) }
color8.setOnClickListener { manageSelectedColor(it) }
color9.setOnClickListener { manageSelectedColor(it) }
binding.color1.setOnClickListener { manageSelectedColor(it) }
binding.color2.setOnClickListener { manageSelectedColor(it) }
binding.color3.setOnClickListener { manageSelectedColor(it) }
binding.color4.setOnClickListener { manageSelectedColor(it) }
binding.color5.setOnClickListener { manageSelectedColor(it) }
binding.color6.setOnClickListener { manageSelectedColor(it) }
binding.color7.setOnClickListener { manageSelectedColor(it) }
binding.color8.setOnClickListener { manageSelectedColor(it) }
binding.color9.setOnClickListener { manageSelectedColor(it) }
}
private fun manageSelectedColor(view: View) {
val color = when(view) {
color1 -> getColor(R.color.player_color_1)
color2 -> getColor(R.color.player_color_2)
color3 -> getColor(R.color.player_color_3)
color4 -> getColor(R.color.player_color_4)
color5 -> getColor(R.color.player_color_5)
color6 -> getColor(R.color.player_color_6)
color7 -> getColor(R.color.player_color_7)
color8 -> getColor(R.color.player_color_8)
color9 -> getColor(R.color.player_color_9)
binding.color1 -> getColor(R.color.player_color_1)
binding.color2 -> getColor(R.color.player_color_2)
binding.color3 -> getColor(R.color.player_color_3)
binding.color4 -> getColor(R.color.player_color_4)
binding.color5 -> getColor(R.color.player_color_5)
binding.color6 -> getColor(R.color.player_color_6)
binding.color7 -> getColor(R.color.player_color_7)
binding.color8 -> getColor(R.color.player_color_8)
binding.color9 -> getColor(R.color.player_color_9)
else -> getColor(R.color.player_color_1)
}

@ -3,12 +3,13 @@ package net.pokeranalytics.android.ui.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_gdpr.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.ActivityGdprBinding
import net.pokeranalytics.android.ui.activity.components.BaseActivity
class GDPRActivity : BaseActivity() {
private lateinit var binding: ActivityGdprBinding
companion object {
fun newInstance(context: Context) {
val intent = Intent(context, GDPRActivity::class.java)
@ -18,7 +19,8 @@ class GDPRActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_gdpr)
binding = ActivityGdprBinding.inflate(layoutInflater)
setContentView(binding.root)
initUI()
}
@ -27,10 +29,8 @@ class GDPRActivity : BaseActivity() {
* Init UI
*/
private fun initUI() {
setSupportActionBar(toolbar)
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
}

@ -6,11 +6,12 @@ import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import com.github.mikephil.charting.data.BarDataSet
import com.github.mikephil.charting.data.LineDataSet
import kotlinx.android.synthetic.main.activity_graph.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.ActivityGraphBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.graph.Graph
import net.pokeranalytics.android.ui.viewmodel.GraphViewModel
import net.pokeranalytics.android.ui.viewmodel.ViewModelHolder
@ -25,7 +26,7 @@ class GraphActivity : BaseActivity(), ViewModelHolder {
private var lineDataSets: List<LineDataSet>? = null
private var barDataSets: List<BarDataSet>? = null
private var style: GraphFragment.Style? = null
private var style: Graph.Style? = null
private var activityTitle: String? = null
/***
@ -33,7 +34,7 @@ class GraphActivity : BaseActivity(), ViewModelHolder {
*/
fun newLineInstance(context: Context, lineDataSets: List<LineDataSet>, title: String? = null) {
this.lineDataSets = lineDataSets
this.style = GraphFragment.Style.LINE
this.style = Graph.Style.LINE
this.activityTitle = title
val intent = Intent(context, GraphActivity::class.java)
@ -45,7 +46,7 @@ class GraphActivity : BaseActivity(), ViewModelHolder {
*/
fun newBarInstance(context: Context, barDataSets: List<BarDataSet>, title: String? = null) {
this.barDataSets = barDataSets
this.style = GraphFragment.Style.BAR
this.style = Graph.Style.BAR
this.activityTitle = title
val intent = Intent(context, GraphActivity::class.java)
@ -54,12 +55,16 @@ class GraphActivity : BaseActivity(), ViewModelHolder {
}
private lateinit var binding: ActivityGraphBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_graph)
binding = ActivityGraphBinding.inflate(layoutInflater)
setContentView(binding.root)
initUI()
}
/**
* Init UI
*/
@ -68,7 +73,7 @@ class GraphActivity : BaseActivity(), ViewModelHolder {
this.model.title = activityTitle
this.model.title?.let {
setSupportActionBar(toolbar)
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
title = activityTitle
activityTitle = null

@ -7,9 +7,9 @@ import android.os.Build
import android.os.Bundle
import com.google.android.material.bottomnavigation.BottomNavigationView
import io.realm.RealmResults
import kotlinx.android.synthetic.main.activity_home.*
import net.pokeranalytics.android.BuildConfig
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.ActivityHomeBinding
import net.pokeranalytics.android.model.realm.Currency
import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.adapter.HomePagerAdapter
@ -56,6 +56,8 @@ class HomeActivity : BaseActivity() {
this.homePagerAdapter?.activityResumed()
}
private lateinit var binding: ActivityHomeBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -68,7 +70,8 @@ class HomeActivity : BaseActivity() {
}
}
setContentView(R.layout.activity_home)
binding = ActivityHomeBinding.inflate(layoutInflater)
setContentView(binding.root)
observeRealmObjects()
initUI()
@ -141,10 +144,12 @@ class HomeActivity : BaseActivity() {
*/
private fun initUI() {
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
navigation.selectedItemId = R.id.navigation_history
binding.navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
binding.navigation.selectedItemId = R.id.navigation_history
homePagerAdapter = HomePagerAdapter(supportFragmentManager)
val viewPager = binding.viewPager
viewPager.offscreenPageLimit = 5
viewPager.enablePaging = false
viewPager.adapter = homePagerAdapter
@ -168,7 +173,7 @@ class HomeActivity : BaseActivity() {
* Display a new fragment
*/
private fun displayFragment(index: Int) {
viewPager.setCurrentItem(index, false)
binding.viewPager.setCurrentItem(index, false)
}
}

@ -10,6 +10,7 @@ import net.pokeranalytics.android.ui.modules.calendar.CalendarFragment
import net.pokeranalytics.android.ui.modules.feed.FeedFragment
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.fragment.components.BaseFragment
import net.pokeranalytics.android.ui.graph.Graph
import java.lang.ref.WeakReference
/**
@ -21,8 +22,8 @@ class ComparisonChartPagerAdapter(val context: Context, fragmentManager: Fragmen
override fun getItem(position: Int): BaseFragment {
return when (position) {
0 -> GraphFragment.newInstance(GraphFragment.Style.BAR)
1 -> GraphFragment.newInstance(GraphFragment.Style.MULTILINE)
0 -> GraphFragment.newInstance(Graph.Style.BAR)
1 -> GraphFragment.newInstance(Graph.Style.MULTILINE)
2 -> CalendarFragment.newInstance()
else -> FeedFragment.newInstance()
}

@ -8,6 +8,7 @@ import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.fragment.components.BaseFragment
import net.pokeranalytics.android.ui.fragment.report.ComposableTableReportFragment
import net.pokeranalytics.android.ui.graph.Graph
import net.pokeranalytics.android.ui.viewmodel.ReportHolder
/**
@ -19,8 +20,8 @@ class ReportPagerAdapter(private val context: Context,
override fun getItem(position: Int): BaseFragment {
return when (position) {
0 -> GraphFragment.newInstance(style = GraphFragment.Style.BAR)
1 -> GraphFragment.newInstance(style = GraphFragment.Style.MULTILINE)
0 -> GraphFragment.newInstance(Graph.Style.BAR)
1 -> GraphFragment.newInstance(Graph.Style.MULTILINE)
2 -> {
val report = this.reportHolder.report
ComposableTableReportFragment.newInstance(report)
@ -33,7 +34,7 @@ class ReportPagerAdapter(private val context: Context,
return 3
}
override fun getPageTitle(position: Int): CharSequence? {
override fun getPageTitle(position: Int): CharSequence {
return when(position) {
0 -> context.getString(R.string.bars)
1 -> context.getString(R.string.lines)

@ -14,9 +14,9 @@ import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.AppCompatTextView
import androidx.appcompat.widget.SearchView
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
@ -147,7 +147,7 @@ fun showAlertDialog(
builder.show()
}
fun AppCompatTextView.setTextFormat(textFormat: TextFormat, context: Context) {
fun TextView.setTextFormat(textFormat: TextFormat, context: Context) {
this.setTextColor(textFormat.getColor(context))
this.text = textFormat.text
}

@ -2,8 +2,8 @@ package net.pokeranalytics.android.ui.fragment
import android.os.Bundle
import android.view.*
import kotlinx.android.synthetic.main.fragment_comparison_chart.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentComparisonChartBinding
import net.pokeranalytics.android.ui.modules.bankroll.BankrollActivity
import net.pokeranalytics.android.ui.activity.SettingsActivity
import net.pokeranalytics.android.ui.adapter.ComparisonChartPagerAdapter
@ -38,12 +38,19 @@ class ComparisonChartFragment : BaseFragment(), StaticRowRepresentableDataSource
private lateinit var viewPagerAdapter: ComparisonChartPagerAdapter
private var comparisonChartMenu: Menu? = null
private var _binding: FragmentComparisonChartBinding? = null
private val binding get() = _binding!!
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_comparison_chart, container, false)
_binding = FragmentComparisonChartBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -97,9 +104,9 @@ class ComparisonChartFragment : BaseFragment(), StaticRowRepresentableDataSource
parentActivity?.let {
viewPagerAdapter = ComparisonChartPagerAdapter(requireContext(), it.supportFragmentManager)
viewPager.adapter = viewPagerAdapter
viewPager.offscreenPageLimit = 2
tabs.setupWithViewPager(viewPager)
binding.viewPager.adapter = viewPagerAdapter
binding.viewPager.offscreenPageLimit = 2
binding.tabs.setupWithViewPager(binding.viewPager)
}
}

@ -8,8 +8,8 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_data_list.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentCurrenciesBinding
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
@ -71,10 +71,20 @@ class CurrenciesFragment : BaseFragment(), StaticRowRepresentableDataSource, Row
override val viewType: Int = RowViewType.TITLE_VALUE.ordinal
}
private var _binding: FragmentCurrenciesBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_currencies, container, false)
}
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = FragmentCurrenciesBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -120,7 +130,7 @@ class CurrenciesFragment : BaseFragment(), StaticRowRepresentableDataSource, Row
val viewManager = LinearLayoutManager(requireContext())
val dataListAdapter = RowRepresentableAdapter(this, this)
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = dataListAdapter

@ -13,12 +13,12 @@ import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.highlight.Highlight
import com.github.mikephil.charting.interfaces.datasets.IBarLineScatterCandleBubbleDataSet
import com.github.mikephil.charting.listener.OnChartValueSelectedListener
import kotlinx.android.synthetic.main.fragment_graph.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.databinding.FragmentGraphBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.interfaces.ObjectIdentifier
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.graph.Graph
import net.pokeranalytics.android.ui.graph.GraphUnderlyingEntry
import net.pokeranalytics.android.ui.graph.setStyle
import net.pokeranalytics.android.ui.view.LegendView
@ -38,18 +38,12 @@ class GraphFragment : RealmFragment(), OnChartValueSelectedListener {
return this.graphDataProvider.stat
}
enum class Style {
LINE,
BAR,
MULTILINE,
}
companion object {
/**
* Create new instance
*/
fun newInstance(style: Style): GraphFragment {
fun newInstance(style: Graph.Style): GraphFragment {
val fragment = GraphFragment()
val bundle = Bundle()
bundle.putSerializable(BundleKey.STYLE.value, style.ordinal)
@ -59,16 +53,27 @@ class GraphFragment : RealmFragment(), OnChartValueSelectedListener {
}
private var style: Style = Style.LINE
private var style: Graph.Style = Graph.Style.LINE
private lateinit var legendView: LegendView
private var chartView: BarLineChartBase<*>? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_graph, container, false)
}
private var _binding: FragmentGraphBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
super.onCreateView(inflater, container, savedInstanceState)
_binding = FragmentGraphBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -79,7 +84,7 @@ class GraphFragment : RealmFragment(), OnChartValueSelectedListener {
private fun initData() {
val styleOrdinal = this.arguments?.getInt(BundleKey.STYLE.value) ?: throw PAIllegalStateException("Missing style key in bundle")
this.style = Style.values()[styleOrdinal]
this.style = Graph.Style.values()[styleOrdinal]
this.graphDataProvider = (requireActivity() as ViewModelHolder).model as GraphDataProvider
}
@ -90,14 +95,14 @@ class GraphFragment : RealmFragment(), OnChartValueSelectedListener {
private fun initUI() {
this.legendView = when (this.style) {
Style.MULTILINE -> MultiLineLegendView(requireContext())
Graph.Style.MULTILINE -> MultiLineLegendView(requireContext())
else -> LegendView(requireContext())
}
this.legendContainer.addView(this.legendView)
this.binding.legendContainer.addView(this.legendView)
}
fun reload(style: Style) {
fun reload(style: Graph.Style) {
this.style = style
if (isAdded && !isDetached) {
loadGraph()
@ -109,14 +114,14 @@ class GraphFragment : RealmFragment(), OnChartValueSelectedListener {
*/
private fun loadGraph() {
this.chartContainer.removeAllViews()
this.binding.chartContainer.removeAllViews()
this.chartView = when (this.style) {
Style.LINE, Style.MULTILINE -> {
Graph.Style.LINE, Graph.Style.MULTILINE -> {
val dataSets = when (this.style) {
Style.LINE -> listOf(this.graphDataProvider.lineDataSet(requireContext()))
Style.MULTILINE -> this.graphDataProvider.multiLineDataSet(requireContext())
Graph.Style.LINE -> listOf(this.graphDataProvider.lineDataSet(requireContext()))
Graph.Style.MULTILINE -> this.graphDataProvider.multiLineDataSet(requireContext())
else -> throw PAIllegalStateException("Cannot happen")
}
@ -136,7 +141,7 @@ class GraphFragment : RealmFragment(), OnChartValueSelectedListener {
lineChart
}
Style.BAR -> {
Graph.Style.BAR -> {
val dataSets = listOf(this.graphDataProvider.barDataSet(requireContext()))
@ -165,7 +170,7 @@ class GraphFragment : RealmFragment(), OnChartValueSelectedListener {
}
}
this.chartContainer.addView(this.chartView)
this.binding.chartContainer.addView(this.chartView)
this.chartView?.setStyle(false, this.graphDataProvider.axisFormatting, requireContext())
@ -199,7 +204,7 @@ class GraphFragment : RealmFragment(), OnChartValueSelectedListener {
val groupName = dataSet?.label ?: ""
val color = dataSet?.color
val legendValue = statEntry.legendValues(stat, entry, this.style, groupName, requireContext())
val legendValue = statEntry.legendValues(stat, entry.y.toDouble(), this.style, groupName, requireContext())
this.legendView.setItemData(legendValue, color)
} else {

@ -6,12 +6,11 @@ import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.fragment_import.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentImportBinding
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.util.csv.CSVImporter
import net.pokeranalytics.android.util.csv.ImportDelegate
@ -19,7 +18,6 @@ import timber.log.Timber
import java.io.InputStream
import java.text.NumberFormat
import java.util.*
import kotlin.coroutines.CoroutineContext
class ImportFragment : RealmFragment(), ImportDelegate {
@ -30,7 +28,24 @@ class ImportFragment : RealmFragment(), ImportDelegate {
private lateinit var inputStream: InputStream
private lateinit var importer: CSVImporter
fun setData(path: String) {
private var _binding: FragmentImportBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
_binding = FragmentImportBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
fun setData(path: String) {
this.filePath = path
}
@ -38,11 +53,6 @@ class ImportFragment : RealmFragment(), ImportDelegate {
this.inputStream = inputStream
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_import, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -53,15 +63,20 @@ class ImportFragment : RealmFragment(), ImportDelegate {
private fun initUI() {
this.imported.text = requireContext().getString(R.string.imported)
this.total.text = requireContext().getString(R.string.total)
val imported = binding.imported
val total = binding.total
val save = binding.save
val cancel = binding.cancel
imported.text = requireContext().getString(R.string.imported)
total.text = requireContext().getString(R.string.total)
this.save.isEnabled = false
this.save.setOnClickListener {
save.isEnabled = false
save.setOnClickListener {
this.end()
}
this.cancel.setOnClickListener {
cancel.setOnClickListener {
this.cancel()
this.end()
}
@ -128,7 +143,7 @@ class ImportFragment : RealmFragment(), ImportDelegate {
private fun importDidFinish() {
this.save.isEnabled = true
binding.save.isEnabled = true
}
@ -141,8 +156,8 @@ class ImportFragment : RealmFragment(), ImportDelegate {
// ImportDelegate
override fun parsingCountUpdate(importedCount: Int, totalCount: Int) {
this.counter.text = this.numberFormatter.format(importedCount)
this.totalCounter.text = this.numberFormatter.format(totalCount)
binding.counter.text = this.numberFormatter.format(importedCount)
binding.totalCounter.text = this.numberFormatter.format(totalCount)
}
}

@ -6,10 +6,10 @@ import android.os.Bundle
import android.view.*
import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.Realm
import kotlinx.android.synthetic.main.fragment_report_creation.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.databinding.FragmentReportCreationBinding
import net.pokeranalytics.android.model.Criteria
import net.pokeranalytics.android.model.CustomFieldCriteria
import net.pokeranalytics.android.model.realm.CustomField
@ -37,10 +37,21 @@ class ReportCreationFragment : RealmFragment(), RowRepresentableDataSource, RowR
private var currentRows: List<RowRepresentable> = listOf()
private var reportCreationMenu: Menu? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_report_creation, container, false)
}
private var _binding: FragmentReportCreationBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
_binding = FragmentReportCreationBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -94,13 +105,13 @@ class ReportCreationFragment : RealmFragment(), RowRepresentableDataSource, RowR
//this.optionsAdapter.setHasStableIds(true)
val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = optionsAdapter
}
this.next.setOnClickListener {
binding.next.setOnClickListener {
if (assistant.nextEnabled) {
this.assistant.nextStep()
@ -126,9 +137,9 @@ class ReportCreationFragment : RealmFragment(), RowRepresentableDataSource, RowR
*/
private fun updateUIWithCurrentStep() {
this.next.visibility = if (this.assistant.nextButtonShouldAppear) View.VISIBLE else View.GONE
this.next.text = requireContext().getString(this.assistant.nextButtonTitleResId)
this.next.isEnabled = this.assistant.nextEnabled
binding.next.visibility = if (this.assistant.nextButtonShouldAppear) View.VISIBLE else View.GONE
binding.next.text = requireContext().getString(this.assistant.nextButtonTitleResId)
binding.next.isEnabled = this.assistant.nextEnabled
this.reportCreationMenu?.findItem(R.id.add)?.isVisible = this.assistant.addButtonShouldAppear
val rows = mutableListOf<RowRepresentable>()
@ -198,7 +209,7 @@ class ReportCreationFragment : RealmFragment(), RowRepresentableDataSource, RowR
if (newStep) {
this.updateUIWithCurrentStep()
} else {
this.next.isEnabled = this.assistant.nextEnabled
binding.next.isEnabled = this.assistant.nextEnabled
this.optionsAdapter.notifyDataSetChanged()
}

@ -10,7 +10,6 @@ import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.Realm
import io.realm.RealmResults
import kotlinx.android.synthetic.main.fragment_data_list.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
@ -18,6 +17,7 @@ import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.databinding.FragmentReportsBinding
import net.pokeranalytics.android.model.Criteria
import net.pokeranalytics.android.model.combined
import net.pokeranalytics.android.model.interfaces.Deletable
@ -59,13 +59,21 @@ class ReportsFragment : DeletableItemFragment(), StaticRowRepresentableDataSourc
}
}
private var _binding: FragmentReportsBinding? = null
private val binding get() = _binding!!
// Life Cycle
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_reports, container, false)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
_binding = FragmentReportsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -119,13 +127,13 @@ class ReportsFragment : DeletableItemFragment(), StaticRowRepresentableDataSourc
val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = dataListAdapter
}
this.addButton.setOnClickListener {
binding.addButton.setOnClickListener {
ReportCreationActivity.newInstanceForResult(this, requireContext())
}

@ -15,9 +15,9 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.android.billingclient.api.Purchase
import com.google.android.play.core.review.ReviewManagerFactory
import io.realm.Realm
import kotlinx.android.synthetic.main.fragment_settings.*
import net.pokeranalytics.android.BuildConfig
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentSettingsBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.realm.Currency
@ -71,7 +71,24 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
private lateinit var settingsAdapterRow: RowRepresentableAdapter
override fun onCreate(savedInstanceState: Bundle?) {
private var _binding: FragmentSettingsBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
_binding = FragmentSettingsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppGuard.registerListener(this)
}
@ -81,11 +98,6 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
AppGuard.unregisterListener(this)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_settings, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initData()
@ -227,7 +239,7 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
val viewManager = LinearLayoutManager(requireContext())
settingsAdapterRow = RowRepresentableAdapter(this, this)
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = settingsAdapterRow

@ -15,6 +15,8 @@ import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputableGroup
import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.databinding.FragmentGraphBinding
import net.pokeranalytics.android.databinding.FragmentStatsBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
@ -46,12 +48,21 @@ class StatisticsFragment : FilterableFragment(), RealmAsyncListener {
}
}
// Life Cycle
private var _binding: FragmentStatsBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_stats, container, false)
}
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
_binding = FragmentStatsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

@ -22,8 +22,8 @@ import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import androidx.viewpager.widget.ViewPager
import com.android.billingclient.api.*
import kotlinx.android.synthetic.main.fragment_subscription.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentSubscriptionBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.utils.CrashLogging
import net.pokeranalytics.android.ui.extensions.px
@ -55,7 +55,23 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
private var selectedProduct: SkuDetails? = null
private var showSessionMessage = false
override fun onCreate(savedInstanceState: Bundle?) {
private var _binding: FragmentSubscriptionBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = FragmentSubscriptionBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val cm = requireContext().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
@ -78,10 +94,6 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_subscription, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initData()
@ -99,6 +111,11 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
private fun initUI() {
val title = binding.title
val message = binding.message
val pager = binding.pager
val purchase = binding.purchase
val pageIndicator = binding.pageIndicator
val upgradeString = requireContext().getString(R.string.pro_upgrade)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
@ -119,25 +136,25 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
}
}
this.title.text = ssb
title.text = ssb
} else {
this.title.text = upgradeString
title.text = upgradeString
}
if (showSessionMessage) {
this.message.text = getString(R.string.iap_session_message)
message.text = getString(R.string.iap_session_message)
}
// Pager
// The pager adapter, which provides the pages to the view pager widget.
this.pagerAdapter = ScreenSlidePagerAdapter(parentFragmentManager)
this.pager.adapter = pagerAdapter
this.pager.addOnPageChangeListener(this)
pager.adapter = pagerAdapter
pager.addOnPageChangeListener(this)
this.purchase.isEnabled = false
this.purchase.setOnClickListener {
purchase.isEnabled = false
purchase.setOnClickListener {
this.selectedProduct?.let {
AppGuard.initiatePurchase(this.requireActivity(), it)
@ -146,13 +163,13 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
}
}
val count = this.pager.adapter?.count ?: 0
val count = pager.adapter?.count ?: 0
for (i in 1..count) {
val view = View(requireContext())
view.background = requireContext().getDrawable(R.drawable.circle_green)
val layoutParam = LinearLayout.LayoutParams(8.px, 8.px)
layoutParam.setMargins(6.px)
this.pageIndicator.addView(view, layoutParam)
pageIndicator.addView(view, layoutParam)
}
this.updatePagerIndicators(0)
@ -210,10 +227,10 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
private fun updateUI() {
this.selectedProduct?.let {
this.purchase.isEnabled = true
binding.purchase.isEnabled = true
val perYearString = requireContext().getString(R.string.year_subscription)
val formattedPrice = it.price + " / " + perYearString
this.price.text = formattedPrice
binding.price.text = formattedPrice
var freeTrialDays = 30 // initial, should be more, no less
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
@ -226,7 +243,7 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
}
val formattedFreeTrial =
"$freeTrialDays " + requireContext().getString(R.string.days) + " " + requireContext().getString(R.string.free_trial)
this.freetrial.text = formattedFreeTrial
binding.freetrial.text = formattedFreeTrial
} ?: run {
Toast.makeText(requireContext(), R.string.contact_support, Toast.LENGTH_LONG).show()
}
@ -261,7 +278,7 @@ class SubscriptionFragment : BaseFragment(), SkuDetailsResponseListener, Purchas
}
private fun updatePagerIndicators(position: Int) {
this.pageIndicator.children.forEachIndexed { index, view ->
binding.pageIndicator.children.forEachIndexed { index, view ->
val drawable = view.background
when (drawable) {
is GradientDrawable -> {

@ -7,8 +7,7 @@ import android.view.ViewGroup
import com.google.android.material.tabs.TabLayout
import io.realm.RealmResults
import io.realm.kotlin.where
import kotlinx.android.synthetic.main.fragment_top_10.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentTop10Binding
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
@ -43,10 +42,21 @@ class Top10Fragment : RealmFragment(), RowRepresentableDataSource, RowRepresenta
private var currentTab: Tab = Tab.CASH_GAMES
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_top_10, container, false)
}
private var _binding: FragmentTop10Binding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
_binding = FragmentTop10Binding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -59,7 +69,10 @@ class Top10Fragment : RealmFragment(), RowRepresentableDataSource, RowRepresenta
*/
private fun initUI() {
dataListAdapter = RowRepresentableAdapter(this, this)
val recyclerView = binding.recyclerView
val tabs = binding.tabs
dataListAdapter = RowRepresentableAdapter(this, this)
recyclerView.adapter = dataListAdapter
setDisplayHomeAsUpEnabled(true)

@ -6,8 +6,9 @@ import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.view.*
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.widget.Toolbar
import kotlinx.android.synthetic.main.view_selected_filter.view.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
@ -57,7 +58,11 @@ open class FilterableFragment : RealmFragment(),
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
parentActivity?.registerReceiver(updateFilterUIBroadcast, IntentFilter(INTENT_FILTER_UPDATE_FILTER_UI))
parentActivity?.registerReceiver(
updateFilterUIBroadcast, IntentFilter(
INTENT_FILTER_UPDATE_FILTER_UI
)
)
}
override fun onDestroy() {
@ -65,7 +70,11 @@ open class FilterableFragment : RealmFragment(),
parentActivity?.unregisterReceiver(updateFilterUIBroadcast)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
setHasOptionsMenu(true)
return super.onCreateView(inflater, container, savedInstanceState)
}
@ -82,9 +91,9 @@ open class FilterableFragment : RealmFragment(),
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_item_filter -> {
manageFilters(this)
}
R.id.menu_item_filter -> {
manageFilters(this)
}
}
return super.onOptionsItemSelected(item)
}
@ -119,9 +128,15 @@ open class FilterableFragment : RealmFragment(),
}
view?.findViewById<ViewGroup>(R.id.selectedFilter)?.let { viewGroup ->
val layoutCurrentFilter = LayoutInflater.from(requireContext()).inflate(R.layout.view_selected_filter, viewGroup, false)
layoutCurrentFilter.filterName.text = filter.getDisplayName(requireContext())
layoutCurrentFilter.deselectFilter.setOnClickListener {
val layoutCurrentFilter = LayoutInflater.from(requireContext()).inflate(
R.layout.view_selected_filter,
viewGroup,
false
)
layoutCurrentFilter.findViewById<TextView>(R.id.filterName)?.text = filter.getDisplayName(
requireContext()
)
layoutCurrentFilter.findViewById<ImageView>(R.id.deselectFilter).setOnClickListener {
saveFilter(requireContext(), "")
}

@ -5,8 +5,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import kotlinx.android.synthetic.main.fragment_loader.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentLoaderBinding
class LoaderDialogFragment: DialogFragment() {
@ -31,15 +30,26 @@ class LoaderDialogFragment: DialogFragment() {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_loader, container, false)
}
private var _binding: FragmentLoaderBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = FragmentLoaderBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
arguments?.let {bundle ->
if (bundle.containsKey(ARGUMENT_MESSAGE_RES_ID)) {
loadingMessage.text = getString(bundle.getInt(ARGUMENT_MESSAGE_RES_ID))
binding.loadingMessage.text = getString(bundle.getInt(ARGUMENT_MESSAGE_RES_ID))
}
}
}

@ -4,8 +4,8 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.fragment_screen_slide_page.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentScreenSlidePageBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
@ -31,20 +31,29 @@ class ScreenSlidePageFragment : BaseFragment() {
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_screen_slide_page, container, false)
private var _binding: FragmentScreenSlidePageBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = FragmentScreenSlidePageBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val bundle = arguments ?: throw PAIllegalStateException("No bundle found")
this.icon.setImageResource(bundle.getInt(BundleKey.ICON.key))
this.title.text = requireContext().getString(bundle.getInt(BundleKey.TITLE.key))
this.description.text = requireContext().getString(bundle.getInt(BundleKey.DESCRIPTION.key))
binding.icon.setImageResource(bundle.getInt(BundleKey.ICON.key))
binding.title.text = requireContext().getString(bundle.getInt(BundleKey.TITLE.key))
binding.description.text = requireContext().getString(bundle.getInt(BundleKey.DESCRIPTION.key))
}
/**

@ -4,29 +4,41 @@ import android.os.Bundle
import android.text.InputType
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.core.widget.addTextChangedListener
import kotlinx.android.synthetic.main.bottom_sheet_double_edit_text.*
import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.BottomSheetDoubleEditTextBinding
import net.pokeranalytics.android.exceptions.RowRepresentableEditDescriptorException
import net.pokeranalytics.android.util.extensions.round
class BottomSheetDoubleEditTextFragment : BottomSheetFragment() {
private var _binding: BottomSheetDoubleEditTextBinding? = null
private val binding get() = _binding!!
override fun getChildView(inflater: LayoutInflater, container: ViewGroup): View? {
_binding = BottomSheetDoubleEditTextBinding.inflate(inflater, container, true)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initData()
initData()
initUI()
}
override fun onStart() {
super.onStart()
if (this.model.isEditingBlinds) {
editText2.requestFocus()
binding.editText2.requestFocus()
} else {
editText.requestFocus()
binding.editText.requestFocus()
}
}
@ -47,56 +59,47 @@ class BottomSheetDoubleEditTextFragment : BottomSheetFragment() {
throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor inconsistency")
}
// values.add(0, "")
// values.add(1, "")
LayoutInflater.from(requireContext())
.inflate(R.layout.bottom_sheet_double_edit_text, view?.bottomSheetContainer, true)
// values[0] = (data[0].defaultValue ?: "").toString()
// values[1] = (data[1].defaultValue ?: "").toString()
data[0].hintResId?.let { editText.hint = getString(it) }
editText.inputType = data[0].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
data[1].hintResId?.let { editText2.hint = getString(it) }
editText2.inputType = data[1].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
data[0].hintResId?.let { binding.editText.hint = getString(it) }
binding.editText.inputType = data[0].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
data[1].hintResId?.let { binding.editText2.hint = getString(it) }
binding.editText2.inputType = data[1].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
if (this.model.valueAsHint) {
this.model.stringValue?.let {
if (it.isNotBlank()) {
editText.hint = it
binding.editText.hint = it
}
}
this.model.secondStringValue?.let {
if (it.isNotBlank()) {
editText2.hint = it
binding.editText2.hint = it
}
}
// if (this.viewModel.stringValue?.isNotBlank()) { editText.hint = values[0] }
// if (values[1].isNotBlank()) { editText2.hint = values[1] }
} else {
editText.setText(this.model.stringValue)
editText2.setText(this.model.secondStringValue)
binding.editText.setText(this.model.stringValue)
binding.editText2.setText(this.model.secondStringValue)
}
editText.addTextChangedListener {
binding.editText.addTextChangedListener {
this.model.stringValue = it?.toString()
}
editText2.addTextChangedListener {
binding.editText2.addTextChangedListener {
this.model.secondStringValue = it?.toString()
if (this.model.isEditingBlinds) {
try {
val bigBlind = this.model.secondStringValue?.toDouble() ?: 0.0
editText.setText((bigBlind / 2.0).round())
binding.editText.setText((bigBlind / 2.0).round())
} catch (e: Exception) {
editText.setText("")
binding.editText.setText("")
}
}
}
editText2.setOnEditorActionListener { _, actionId, _ ->
binding.editText2.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
this.onRowValueChanged()
// this.delegate.onRowValueChanged(values, row)

@ -4,38 +4,48 @@ import android.os.Bundle
import android.text.InputType
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.core.widget.addTextChangedListener
import kotlinx.android.synthetic.main.bottom_sheet_edit_text.*
import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.BottomSheetEditTextBinding
import net.pokeranalytics.android.exceptions.RowRepresentableEditDescriptorException
class BottomSheetEditTextFragment : BottomSheetFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
private var _binding: BottomSheetEditTextBinding? = null
private val binding get() = _binding!!
override fun getChildView(inflater: LayoutInflater, container: ViewGroup): View? {
_binding = BottomSheetEditTextBinding.inflate(inflater, container, true)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initUI()
}
override fun onStart() {
super.onStart()
editText.requestFocus()
binding.editText.requestFocus()
}
/**
* Init UI
*/
private fun initUI() {
val editText = binding.editText
val data = getDescriptors() ?: throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor not found for $this")
if (data.size != 1) {
throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor inconsistency")
}
LayoutInflater.from(requireContext()).inflate(R.layout.bottom_sheet_edit_text, view?.bottomSheetContainer, true)
data[0].hintResId?.let { editText.hint = getString(it) }
editText.inputType = data[0].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
editText.addTextChangedListener {

@ -4,14 +4,27 @@ import android.os.Bundle
import android.text.InputType
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.addTextChangedListener
import kotlinx.android.synthetic.main.bottom_sheet_edit_text_multi_lines.*
import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.*
import net.pokeranalytics.android.databinding.BottomSheetEditTextMultiLinesBinding
import net.pokeranalytics.android.exceptions.RowRepresentableEditDescriptorException
class BottomSheetEditTextMultiLinesFragment : BottomSheetFragment() {
private var _binding: BottomSheetEditTextMultiLinesBinding? = null
private val binding get() = _binding!!
override fun getChildView(inflater: LayoutInflater, container: ViewGroup): View? {
_binding = BottomSheetEditTextMultiLinesBinding.inflate(inflater, container, true)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initUI()
@ -19,20 +32,19 @@ class BottomSheetEditTextMultiLinesFragment : BottomSheetFragment() {
override fun onStart() {
super.onStart()
editText.requestFocus()
binding.editText.requestFocus()
}
/**
* Init UI
*/
private fun initUI() {
val editText = binding.editText
val data = getDescriptors() ?: throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor not found")
if (data.size != 1) {
throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor inconsistency")
}
LayoutInflater.from(requireContext()).inflate(net.pokeranalytics.android.R.layout.bottom_sheet_edit_text_multi_lines, view?.bottomSheetContainer, true)
data[0].hintResId?.let { editText.hint = getString(it) }
editText.inputType = data[0].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
editText.addTextChangedListener { this.model.stringValue = it?.toString() }

@ -9,11 +9,10 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.appcompat.view.ContextThemeWrapper
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.fragment_bottom_sheet.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentBottomSheetBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.ui.activity.components.BaseActivity
@ -46,6 +45,9 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
protected lateinit var dataAdapter: RowRepresentableAdapter
private var _binding: FragmentBottomSheetBinding? = null
private val binding get() = _binding!!
companion object {
private var config: BottomSheetConfig? = null
@ -91,11 +93,22 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
//TODO: When dependency 'com.google.android.material:material:1.1.0' will be available in stable version, upgrade and remove that
val contextThemeWrapper = ContextThemeWrapper(activity, R.style.PokerAnalyticsTheme)
return inflater.cloneInContext(contextThemeWrapper).inflate(R.layout.fragment_bottom_sheet, container, false)
activity?.setTheme(R.style.PokerAnalyticsTheme)
_binding = FragmentBottomSheetBinding.inflate(inflater, container, false)
binding.bottomSheetContainer.addView(getChildView(inflater, binding.root))
return binding.root
}
private fun initModel() {
open fun getChildView(inflater: LayoutInflater, container: ViewGroup): View? {
return null
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun initModel() {
val row = config?.row
?: (requireActivity() as? BaseActivity)?.bottomSheetViewModel?.rowRepresentable
@ -174,6 +187,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
private fun initUI() {
val row = this.model.row
val bottomSheetToolbar = binding.bottomSheetToolbar
bottomSheetToolbar.title = row.localizedTitle(requireContext())
bottomSheetToolbar.inflateMenu(R.menu.toolbar_bottom_sheet)
bottomSheetToolbar.setOnMenuItemClickListener {

@ -3,10 +3,9 @@ package net.pokeranalytics.android.ui.fragment.components.bottomsheet
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.bottom_sheet_list.*
import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.BottomSheetListBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.ui.adapter.LiveRowRepresentableDataSource
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
@ -16,6 +15,19 @@ import net.pokeranalytics.android.ui.view.RowViewType
open class BottomSheetListFragment : BottomSheetFragment(), LiveRowRepresentableDataSource, RowRepresentableDelegate {
private var _binding: BottomSheetListBinding? = null
private val binding get() = _binding!!
override fun getChildView(inflater: LayoutInflater, container: ViewGroup): View? {
_binding = BottomSheetListBinding.inflate(inflater, container, true)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun adapterRows(): List<RowRepresentable>? {
return this.model.realmData
}
@ -82,13 +94,11 @@ open class BottomSheetListFragment : BottomSheetFragment(), LiveRowRepresentable
* Init UI
*/
open fun initUI() {
LayoutInflater.from(requireContext()).inflate(R.layout.bottom_sheet_list, view?.bottomSheetContainer, true)
val viewManager = LinearLayoutManager(requireContext())
val dataAdapter = RowRepresentableAdapter(this, this)
this.dataAdapter = dataAdapter
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = dataAdapter

@ -3,12 +3,11 @@ package net.pokeranalytics.android.ui.fragment.components.bottomsheet
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.get
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.chip.Chip
import kotlinx.android.synthetic.main.bottom_sheet_game_list.*
import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.BottomSheetGameListBinding
import net.pokeranalytics.android.model.Limit
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.extensions.px
@ -20,6 +19,19 @@ import net.pokeranalytics.android.ui.view.RowRepresentable
*/
class BottomSheetListGameFragment : BottomSheetListFragment() {
private var _binding: BottomSheetGameListBinding? = null
private val binding get() = _binding!!
override fun getChildView(inflater: LayoutInflater, container: ViewGroup): View? {
_binding = BottomSheetGameListBinding.inflate(inflater, container, true)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initUI()
@ -41,8 +53,7 @@ class BottomSheetListGameFragment : BottomSheetListFragment() {
* Init UI
*/
override fun initUI() {
LayoutInflater.from(requireContext()).inflate(R.layout.bottom_sheet_game_list, view?.bottomSheetContainer, true)
val chipGroup = binding.chipGroup
val limit = this.model.limit
this.model.someValues.add(0, limit)
@ -71,7 +82,7 @@ class BottomSheetListGameFragment : BottomSheetListFragment() {
val dataAdapter = RowRepresentableAdapter(this, this)
this.dataAdapter = dataAdapter
recyclerView2.apply {
binding.recyclerView2.apply {
setHasFixedSize(true)
layoutManager = viewManager2
adapter = dataAdapter

@ -2,7 +2,11 @@ package net.pokeranalytics.android.ui.fragment.components.bottomsheet
import android.app.Activity
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import io.realm.RealmModel
import net.pokeranalytics.android.databinding.BottomSheetDoubleEditTextBinding
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.ui.modules.data.EditableDataActivity
import net.pokeranalytics.android.ui.activity.components.BaseActivity
@ -14,6 +18,19 @@ import net.pokeranalytics.android.ui.view.RowViewType
*/
open class BottomSheetMultiSelectionFragment : BottomSheetListFragment() {
private var _binding: BottomSheetDoubleEditTextBinding? = null
private val binding get() = _binding!!
override fun getChildView(inflater: LayoutInflater, container: ViewGroup): View? {
_binding = BottomSheetDoubleEditTextBinding.inflate(inflater, container, true)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun viewTypeForPosition(position: Int): Int {
return RowViewType.TITLE_CHECK.ordinal
}

@ -4,17 +4,29 @@ import android.os.Bundle
import android.text.InputType
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.core.widget.addTextChangedListener
import kotlinx.android.synthetic.main.bottom_sheet_edit_text.*
import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.BottomSheetEditTextBinding
import net.pokeranalytics.android.exceptions.RowRepresentableEditDescriptorException
import java.text.NumberFormat
class BottomSheetNumericTextFragment : BottomSheetFragment() {
private var _binding: BottomSheetEditTextBinding? = null
private val binding get() = _binding!!
override fun getChildView(inflater: LayoutInflater, container: ViewGroup): View? {
_binding = BottomSheetEditTextBinding.inflate(inflater, container, true)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initUI()
@ -22,20 +34,19 @@ class BottomSheetNumericTextFragment : BottomSheetFragment() {
override fun onStart() {
super.onStart()
editText.requestFocus()
binding.editText.requestFocus()
}
/**
* Init UI
*/
private fun initUI() {
val editText = binding.editText
val data = getDescriptors()?:throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor not found")
if (data.size != 1) {
throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor inconsistency")
}
LayoutInflater.from(requireContext()).inflate(R.layout.bottom_sheet_edit_text, view?.bottomSheetContainer, true)
data[0].hintResId?.let { editText.hint = getString(it) }
editText.inputType = data[0].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES

@ -3,10 +3,9 @@ package net.pokeranalytics.android.ui.fragment.components.bottomsheet
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.bottom_sheet_list.*
import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.BottomSheetListBinding
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
@ -15,10 +14,20 @@ import net.pokeranalytics.android.ui.view.RowRepresentable
class BottomSheetStaticListFragment : BottomSheetFragment(), StaticRowRepresentableDataSource,
RowRepresentableDelegate {
// private var staticRows: List<RowRepresentable> = emptyList()
// private lateinit var dataAdapter: RowRepresentableAdapter
private var _binding: BottomSheetListBinding? = null
private val binding get() = _binding!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
override fun getChildView(inflater: LayoutInflater, container: ViewGroup): View? {
_binding = BottomSheetListBinding.inflate(inflater, container, true)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initUI()
}
@ -45,13 +54,12 @@ class BottomSheetStaticListFragment : BottomSheetFragment(), StaticRowRepresenta
* Init UI
*/
private fun initUI() {
LayoutInflater.from(requireContext()).inflate(R.layout.bottom_sheet_list, view?.bottomSheetContainer, true)
val viewManager = LinearLayoutManager(requireContext())
val dataAdapter = RowRepresentableAdapter(this, this)
this.dataAdapter = dataAdapter
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = dataAdapter

@ -4,11 +4,10 @@ import android.os.Bundle
import android.text.InputType
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.core.widget.addTextChangedListener
import kotlinx.android.synthetic.main.bottom_sheet_sum.*
import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.BottomSheetSumBinding
import net.pokeranalytics.android.exceptions.RowRepresentableEditDescriptorException
import net.pokeranalytics.android.util.extensions.round
import net.pokeranalytics.android.util.extensions.toCurrency
@ -17,14 +16,27 @@ import java.text.NumberFormat
class BottomSheetSumFragment : BottomSheetFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
private var _binding: BottomSheetSumBinding? = null
private val binding get() = _binding!!
override fun getChildView(inflater: LayoutInflater, container: ViewGroup): View? {
_binding = BottomSheetSumBinding.inflate(inflater, container, true)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initUI()
}
override fun onStart() {
super.onStart()
editText.requestFocus()
binding.editText.requestFocus()
}
@ -32,11 +44,16 @@ class BottomSheetSumFragment : BottomSheetFragment() {
* Init UI
*/
private fun initUI() {
val currentValue = binding.currentValue
val editText = binding.editText
val editText2 = binding.editText2
val button1 = binding.button1
val button2 = binding.button2
val data = getDescriptors()?:throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor not found")
if (data.size != 5) {
throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor inconsistency")
}
LayoutInflater.from(requireContext()).inflate(R.layout.bottom_sheet_sum, view?.bottomSheetContainer, true)
if (data.size == 5) {

@ -3,10 +3,9 @@ package net.pokeranalytics.android.ui.fragment.components.bottomsheet
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import kotlinx.android.synthetic.main.bottom_sheet_grid.*
import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.BottomSheetGridBinding
import net.pokeranalytics.android.model.TableSize
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
@ -17,9 +16,20 @@ import net.pokeranalytics.android.ui.view.RowRepresentable
class BottomSheetTableSizeGridFragment : BottomSheetFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate {
// private lateinit var dataAdapter: RowRepresentableAdapter
private var _binding: BottomSheetGridBinding? = null
private val binding get() = _binding!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
override fun getChildView(inflater: LayoutInflater, container: ViewGroup): View? {
_binding = BottomSheetGridBinding.inflate(inflater, container, true)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initUI()
}
@ -34,8 +44,6 @@ class BottomSheetTableSizeGridFragment : BottomSheetFragment(), StaticRowReprese
* Init UI
*/
private fun initUI() {
LayoutInflater.from(requireContext())
.inflate(R.layout.bottom_sheet_grid, view?.bottomSheetContainer, true)
val viewManager = GridLayoutManager(requireContext(), 3)
val dataAdapter = RowRepresentableAdapter(this, this)
@ -45,7 +53,7 @@ class BottomSheetTableSizeGridFragment : BottomSheetFragment(), StaticRowReprese
val spacing = 2.px
val includeEdge = false
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = dataAdapter

@ -5,8 +5,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.tabs.TabLayout
import kotlinx.android.synthetic.main.fragment_report_details.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentReportDetailsBinding
import net.pokeranalytics.android.ui.adapter.ReportPagerAdapter
class ComparisonReportFragment : AbstractReportFragment() {
@ -21,10 +20,21 @@ class ComparisonReportFragment : AbstractReportFragment() {
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_report_details, container, false)
}
private var _binding: FragmentReportDetailsBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
_binding = FragmentReportDetailsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -36,6 +46,9 @@ class ComparisonReportFragment : AbstractReportFragment() {
*/
private fun initUI() {
val viewPager = binding.viewPager
val tabs = binding.tabs
viewPager.adapter = ReportPagerAdapter(requireContext(), requireActivity().supportFragmentManager, this.reportViewModel)
// setDisplayHomeAsUpEnabled(true)

@ -7,7 +7,6 @@ import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.Realm
import kotlinx.android.synthetic.main.fragment_composable_table_report.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
@ -17,6 +16,7 @@ import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputableGroup
import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.databinding.FragmentComposableTableReportBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.realm.ComputableResult
import net.pokeranalytics.android.ui.activity.components.ReportActivity
@ -39,34 +39,43 @@ open class ComposableTableReportFragment : RealmFragment(), StaticRowRepresentab
// override val coroutineContext: CoroutineContext
// get() = Dispatchers.Main
private var rowRepresentables: ArrayList<RowRepresentable> = ArrayList()
companion object {
/**
* Create new instance
*/
fun newInstance(report: Report? = null): ComposableTableReportFragment {
val fragment = ComposableTableReportFragment()
fragment.report = report
val bundle = Bundle()
fragment.arguments = bundle
return fragment
}
}
private var rowRepresentables: ArrayList<RowRepresentable> = ArrayList()
private var statsAdapter: RowRepresentableAdapter? = null
var report: Report? = null
private var hasComputationInProgress: Boolean = false
companion object {
/**
* Create new instance
*/
fun newInstance(report: Report? = null): ComposableTableReportFragment {
val fragment = ComposableTableReportFragment()
fragment.report = report
val bundle = Bundle()
fragment.arguments = bundle
return fragment
}
}
private var _binding: FragmentComposableTableReportBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_composable_table_report, container, false)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
_binding = FragmentComposableTableReportBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -126,7 +135,7 @@ open class ComposableTableReportFragment : RealmFragment(), StaticRowRepresentab
open fun initUI() {
val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = statsAdapter

@ -11,15 +11,19 @@ import com.github.mikephil.charting.data.LineDataSet
import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup
import io.realm.Realm
import kotlinx.android.synthetic.main.fragment_progress_report.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calcul.barEntries
import net.pokeranalytics.android.calcul.defaultStatEntries
import net.pokeranalytics.android.calcul.durationEntries
import net.pokeranalytics.android.calcul.lineEntries
import net.pokeranalytics.android.calculus.AggregationType
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.databinding.FragmentProgressReportBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.combined
import net.pokeranalytics.android.ui.extensions.ChipGroupExtension
@ -27,6 +31,7 @@ import net.pokeranalytics.android.ui.extensions.hideWithAnimation
import net.pokeranalytics.android.ui.extensions.px
import net.pokeranalytics.android.ui.extensions.showWithAnimation
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.graph.Graph
import timber.log.Timber
import java.util.*
@ -38,7 +43,7 @@ class ProgressReportFragment : AbstractReportFragment() {
/**
* Creates new instance
*/
fun newInstance(style: GraphFragment.Style? = null): ProgressReportFragment {
fun newInstance(style: Graph.Style? = null): ProgressReportFragment {
val fragment = ProgressReportFragment()
val bundle = Bundle()
style?.let {
@ -53,10 +58,21 @@ class ProgressReportFragment : AbstractReportFragment() {
private var reports: MutableMap<AggregationType, Report> = EnumMap(AggregationType::class.java)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_progress_report, container, false)
}
private var _binding: FragmentProgressReportBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
_binding = FragmentProgressReportBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -68,9 +84,10 @@ class ProgressReportFragment : AbstractReportFragment() {
*/
private fun initUI() {
val chipGroup = binding.chipGroup
val fragmentManager = parentActivity?.supportFragmentManager
val fragmentTransaction = fragmentManager?.beginTransaction()
this.graphFragment = GraphFragment.newInstance(GraphFragment.Style.LINE)
this.graphFragment = GraphFragment.newInstance(Graph.Style.LINE)
fragmentTransaction?.add(R.id.graphContainer, this.graphFragment)
fragmentTransaction?.commit()
@ -92,14 +109,14 @@ class ProgressReportFragment : AbstractReportFragment() {
chip.text = requireContext().getString(type.resId)
chip.chipStartPadding = 8f.px
chip.chipEndPadding = 8f.px
this.chipGroup.addView(chip)
chipGroup.addView(chip)
}
this.chipGroup.isVisible = this.reportViewModel.showAggregationChoices
this.chipGroup.isSingleSelection = true
this.chipGroup.check(0)
chipGroup.isVisible = this.reportViewModel.showAggregationChoices
chipGroup.isSingleSelection = true
chipGroup.check(0)
this.chipGroup.setOnCheckedChangeListener(object : ChipGroupExtension.SingleSelectionOnCheckedListener() {
chipGroup.setOnCheckedChangeListener(object : ChipGroupExtension.SingleSelectionOnCheckedListener() {
override fun onCheckedChanged(group: ChipGroup, checkedId: Int) {
super.onCheckedChanged(group, checkedId)
@ -136,6 +153,9 @@ class ProgressReportFragment : AbstractReportFragment() {
*/
private fun launchStatComputation(aggregationType: AggregationType) {
val graphContainer = binding.graphContainer
val progressBar = binding.progressBar
graphContainer.hideWithAnimation()
progressBar.showWithAnimation()
@ -188,11 +208,11 @@ class ProgressReportFragment : AbstractReportFragment() {
when (ds) {
is LineDataSet -> {
this.reportViewModel.setLineDataSet(ds)
graphFragment.reload(GraphFragment.Style.LINE)
graphFragment.reload(Graph.Style.LINE)
}
is BarDataSet -> {
this.reportViewModel.setBarDataSet(ds)
graphFragment.reload(GraphFragment.Style.BAR)
graphFragment.reload(Graph.Style.BAR)
}
else -> throw PAIllegalStateException("unmanaged data set")
}

@ -5,11 +5,10 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentTableReportBinding
class TableReportFragment : AbstractReportFragment() {
private lateinit var tableReportFragment: ComposableTableReportFragment
companion object {
fun newInstance(): TableReportFragment {
@ -20,10 +19,23 @@ class TableReportFragment : AbstractReportFragment() {
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_table_report, container, false)
}
private lateinit var tableReportFragment: ComposableTableReportFragment
private var _binding: FragmentTableReportBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
_binding = FragmentTableReportBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

@ -8,15 +8,10 @@ import com.github.mikephil.charting.charts.BarChart
import com.github.mikephil.charting.charts.BarLineChartBase
import com.github.mikephil.charting.components.XAxis
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.AxisFormatting
import net.pokeranalytics.android.model.utils.CrashLogging
import net.pokeranalytics.android.ui.extensions.px
enum class AxisFormatting {
DEFAULT,
X_DURATION,
Y_DURATION,
}
fun BarLineChartBase<*>.setStyle(
small: Boolean,
axisFormatting: AxisFormatting = AxisFormatting.DEFAULT,

@ -1,13 +1,19 @@
package net.pokeranalytics.android.ui.graph
import android.content.Context
import com.github.mikephil.charting.data.Entry
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.view.DefaultLegendValues
import net.pokeranalytics.android.ui.view.LegendContent
import net.pokeranalytics.android.util.TextFormat
interface Graph {
enum class Style {
LINE,
BAR,
MULTILINE,
}
}
interface GraphUnderlyingEntry {
fun entryTitle(context: Context): String
@ -15,14 +21,14 @@ interface GraphUnderlyingEntry {
fun legendValues(
stat: Stat,
entry: Entry,
style: GraphFragment.Style,
total: Double,
style: Graph.Style,
groupName: String,
context: Context
): LegendContent {
val leftName = stat.localizedTitle(context)
val totalStatValue = stat.textFormat(entry.y.toDouble(), currency = null)
val totalStatValue = stat.textFormat(total, currency = null)
return if (stat.legendHideRightValue) {
DefaultLegendValues(this.entryTitle(context), totalStatValue, leftName = leftName)

@ -5,12 +5,12 @@ import android.content.Intent
import android.os.Bundle
import android.view.*
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_bankroll.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.bankroll.BankrollReport
import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager
import net.pokeranalytics.android.databinding.FragmentBankrollDetailsBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.realm.Bankroll
@ -47,11 +47,16 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc
private var bankrollDetailsMenu: Menu? = null
private var _binding: FragmentBankrollDetailsBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_bankroll_details, container, false)
_binding = FragmentBankrollDetailsBinding.inflate(inflater, container, false)
return binding.root
// return inflater.inflate(R.layout.fragment_bankroll_details, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -81,6 +86,11 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc
super.onCreateOptionsMenu(menu, inflater)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
/**
* Init data
*/
@ -104,7 +114,7 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc
val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply {
this.binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = bankrollAdapter
@ -188,7 +198,7 @@ class BankrollDetailsFragment : RealmFragment(), StaticRowRepresentableDataSourc
// StaticRowRepresentableDataSource
override fun adapterRows(): List<RowRepresentable>? {
override fun adapterRows(): List<RowRepresentable> {
return rows
}

@ -9,13 +9,14 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.mikephil.charting.data.LineDataSet
import io.realm.RealmResults
import kotlinx.android.synthetic.main.fragment_bankroll.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager
import net.pokeranalytics.android.databinding.FragmentBankrollBinding
import net.pokeranalytics.android.databinding.FragmentBankrollDetailsBinding
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.interfaces.Deletable
import net.pokeranalytics.android.model.realm.Bankroll
@ -62,6 +63,9 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour
private lateinit var bankrolls: RealmResults<Bankroll>
private var _binding: FragmentBankrollBinding? = null
private val binding get() = _binding!!
override fun deletableItems(): List<Deletable> {
return this.bankrolls
}
@ -70,7 +74,8 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_bankroll, container, false)
_binding = FragmentBankrollBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -103,6 +108,11 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
/**
* Init data
*/
@ -153,13 +163,13 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour
val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply {
this.binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = dataListAdapter
}
addButton.setOnClickListener {
this.binding.addButton.setOnClickListener {
EditableDataActivity.newInstanceForResult(
this@BankrollFragment,
dataType = LiveData.BANKROLL,

@ -13,13 +13,14 @@ import com.github.mikephil.charting.data.BarDataSet
import com.github.mikephil.charting.data.LineDataSet
import com.google.android.material.tabs.TabLayout
import io.realm.Realm
import kotlinx.android.synthetic.main.fragment_calendar_details.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calcul.defaultStatEntries
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.databinding.FragmentCalendarDetailsBinding
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.ui.activity.GraphActivity
@ -53,22 +54,12 @@ class CalendarDetailsFragment : BaseFragment(), StaticRowRepresentableDataSource
private var rowRepresentables: ArrayList<RowRepresentable> = ArrayList()
/**
* Set data
*/
// fun setData(computedResults: ComputedResults?, sessionTypeCondition: QueryCondition?, title: String?) {
//
// this.computedResults = computedResults
// this.sessionTypeCondition = sessionTypeCondition
// this.title = title
//
// displayData()
// launchStatComputation()
//
// }
private var _binding: FragmentCalendarDetailsBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_calendar_details, container, false)
_binding = FragmentCalendarDetailsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -77,6 +68,11 @@ class CalendarDetailsFragment : BaseFragment(), StaticRowRepresentableDataSource
launchStatComputation()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
/**
* Init UI
*/
@ -95,9 +91,9 @@ class CalendarDetailsFragment : BaseFragment(), StaticRowRepresentableDataSource
}
}
tabs.getTabAt(tabIndexToSelect)?.select()
this.binding.tabs.getTabAt(tabIndexToSelect)?.select()
tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
this.binding.tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
when (tab.position) {
0 -> model.sessionTypeCondition = null
@ -118,7 +114,7 @@ class CalendarDetailsFragment : BaseFragment(), StaticRowRepresentableDataSource
val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply {
this.binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = statsAdapter
@ -129,7 +125,7 @@ class CalendarDetailsFragment : BaseFragment(), StaticRowRepresentableDataSource
// StaticRowRepresentableDataSource
override fun adapterRows(): List<RowRepresentable>? {
override fun adapterRows(): List<RowRepresentable> {
return rowRepresentables
}
@ -164,9 +160,9 @@ class CalendarDetailsFragment : BaseFragment(), StaticRowRepresentableDataSource
*/
private fun launchStatComputation() {
progressBar.isVisible = true
progressBar.animate().alpha(1f).start()
recyclerView.animate().alpha(0f).start()
this.binding.progressBar.isVisible = true
this.binding.progressBar.animate().alpha(1f).start()
this.binding.recyclerView.animate().alpha(0f).start()
this.model.computedResults?.let { computedResults ->
@ -226,10 +222,10 @@ class CalendarDetailsFragment : BaseFragment(), StaticRowRepresentableDataSource
launch(Dispatchers.Main) {
statsAdapter.notifyDataSetChanged()
progressBar.animate().cancel()
progressBar.animate().alpha(0f).withEndAction { progressBar.isVisible = false }.start()
recyclerView.animate().cancel()
recyclerView.animate().alpha(1f).start()
binding.progressBar.animate().cancel()
binding.progressBar.animate().alpha(0f).withEndAction { binding.progressBar.isVisible = false }.start()
binding.recyclerView.animate().cancel()
binding.recyclerView.animate().alpha(1f).start()
}
}
}

@ -7,15 +7,14 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.tabs.TabLayout
import io.realm.Realm
import kotlinx.android.synthetic.main.fragment_calendar.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputedResults
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.databinding.FragmentCalendarBinding
import net.pokeranalytics.android.model.Criteria
import net.pokeranalytics.android.model.combined
import net.pokeranalytics.android.model.filter.QueryCondition
@ -72,11 +71,15 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
TimeFilter.MONTH
private var currentStat = Stat.NET_RESULT
private var _binding: FragmentCalendarBinding? = null
private val binding get() = _binding!!
// Life Cycle
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_calendar, container, false)
_binding = FragmentCalendarBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -86,7 +89,14 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
listenRealmChanges(this, ComputableResult::class.java)
}
override fun adapterRows(): List<RowRepresentable>? {
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
//
override fun adapterRows(): List<RowRepresentable> {
return rows
}
@ -134,12 +144,12 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
private fun initUI() {
CalendarTabs.values().forEach {
val tab = tabs.newTab()
val tab = binding.tabs.newTab()
tab.text = getString(it.resId)
tabs.addTab(tab)
binding.tabs.addTab(tab)
}
tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
binding.tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
when (tab.position) {
0 -> currentStat = Stat.NET_RESULT
@ -162,57 +172,57 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
})
// Manage session type queryWith
filterSessionAll.setOnCheckedChangeListener { _, isChecked ->
binding.filterSessionAll.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
sessionTypeCondition = null
filterSessionCash.isChecked = false
filterSessionTournament.isChecked = false
binding.filterSessionCash.isChecked = false
binding.filterSessionTournament.isChecked = false
launchAsyncStatComputation()
} else if (sessionTypeCondition == null) {
filterSessionAll.isChecked = true
binding.filterSessionAll.isChecked = true
}
}
filterSessionCash.setOnCheckedChangeListener { _, isChecked ->
binding.filterSessionCash.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
sessionTypeCondition = QueryCondition.IsCash
filterSessionAll.isChecked = false
filterSessionTournament.isChecked = false
binding.filterSessionAll.isChecked = false
binding.filterSessionTournament.isChecked = false
launchAsyncStatComputation()
} else if (sessionTypeCondition == QueryCondition.IsCash) {
filterSessionCash.isChecked = true
binding.filterSessionCash.isChecked = true
}
}
filterSessionTournament.setOnCheckedChangeListener { _, isChecked ->
binding.filterSessionTournament.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
sessionTypeCondition = QueryCondition.IsTournament
filterSessionAll.isChecked = false
filterSessionCash.isChecked = false
binding.filterSessionAll.isChecked = false
binding.filterSessionCash.isChecked = false
launchAsyncStatComputation()
} else if (sessionTypeCondition == QueryCondition.IsTournament) {
filterSessionTournament.isChecked = true
binding.filterSessionTournament.isChecked = true
}
}
// Manage time queryWith
filterTimeMonth.setOnCheckedChangeListener { _, isChecked ->
binding.filterTimeMonth.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
currentTimeFilter =
TimeFilter.MONTH
filterTimeYear.isChecked = false
binding.filterTimeYear.isChecked = false
displayData()
} else if (currentTimeFilter == TimeFilter.MONTH) {
filterTimeMonth.isChecked = true
binding.filterTimeMonth.isChecked = true
}
}
filterTimeYear.setOnCheckedChangeListener { _, isChecked ->
binding.filterTimeYear.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
currentTimeFilter =
TimeFilter.YEAR
filterTimeMonth.isChecked = false
binding.filterTimeMonth.isChecked = false
displayData()
} else if (currentTimeFilter == TimeFilter.YEAR) {
filterTimeYear.isChecked = true
binding.filterTimeYear.isChecked = true
}
}
@ -220,7 +230,7 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
calendarAdapter = RowRepresentableAdapter(this, this)
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = calendarAdapter
@ -232,8 +242,8 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
*/
private fun launchAsyncStatComputation() {
progressBar?.showWithAnimation()
recyclerView?.hideWithAnimation()
binding.progressBar?.showWithAnimation()
binding.recyclerView?.hideWithAnimation()
GlobalScope.launch {
@ -411,8 +421,8 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
calendarAdapter.notifyDataSetChanged()
progressBar?.hideWithAnimation()
recyclerView?.showWithAnimation()
binding.progressBar.hideWithAnimation()
binding.recyclerView.showWithAnimation()
}

@ -9,17 +9,15 @@ import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.chip.ChipGroup
import kotlinx.android.synthetic.main.fragment_custom_view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentCustomViewBinding
import net.pokeranalytics.android.model.realm.CustomField
import net.pokeranalytics.android.model.realm.CustomFieldEntry
import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.extensions.ChipGroupExtension
import net.pokeranalytics.android.ui.extensions.px
import net.pokeranalytics.android.ui.extensions.showAlertDialog
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomFieldRow
@ -102,18 +100,25 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa
}
})
private var _binding: FragmentCustomViewBinding? = null
private val binding get() = _binding!!
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)
return inflater.inflate(R.layout.fragment_custom_view, container, false)
_binding = FragmentCustomViewBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initUI()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun getDataSource(): RowRepresentableDataSource {
return this
}
@ -205,29 +210,34 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa
* Init UI
*/
private fun initUI() {
val addItem = binding.addItem
val sortChoices = binding.sortChoices
val sortDescending = binding.sortDescending
val recyclerView = binding.recyclerView
customField.updateRowRepresentation()
bottomBar.translationY = 72f.px
bottomBar.visibility = View.VISIBLE
binding.bottomBar.translationY = 72f.px
binding.bottomBar.visibility = View.VISIBLE
if (customField.sortCondition == CustomField.Sort.DEFAULT.uniqueIdentifier) {
itemTouchHelper.attachToRecyclerView(recyclerView)
itemTouchHelper.attachToRecyclerView(binding.recyclerView)
} else {
itemTouchHelper.attachToRecyclerView(null)
}
when (customField.sortCondition) {
CustomField.Sort.DEFAULT.uniqueIdentifier -> sortDefault.isChecked = true
CustomField.Sort.ASCENDING.uniqueIdentifier -> sortAscending.isChecked = true
CustomField.Sort.DESCENDING.uniqueIdentifier -> sortDescending.isChecked = true
CustomField.Sort.DEFAULT.uniqueIdentifier -> binding.sortDefault.isChecked = true
CustomField.Sort.ASCENDING.uniqueIdentifier -> binding.sortAscending.isChecked = true
CustomField.Sort.DESCENDING.uniqueIdentifier -> binding.sortDescending.isChecked = true
}
addItem.setOnClickListener {
binding.addItem.setOnClickListener {
val customFieldEntry = customField.addEntry()
rowRepresentableAdapter.notifyDataSetChanged()
onRowSelected(-1, customFieldEntry)
}
sortChoices.setOnCheckedChangeListener(object : ChipGroupExtension.SingleSelectionOnCheckedListener() {
binding.sortChoices.setOnCheckedChangeListener(object : ChipGroupExtension.SingleSelectionOnCheckedListener() {
override fun onCheckedChanged(group: ChipGroup, checkedId: Int) {
super.onCheckedChanged(group, checkedId)
@ -243,7 +253,7 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa
}
if (customField.sortCondition == CustomField.Sort.DEFAULT.uniqueIdentifier) {
itemTouchHelper.attachToRecyclerView(recyclerView)
itemTouchHelper.attachToRecyclerView(binding.recyclerView)
} else {
itemTouchHelper.attachToRecyclerView(null)
}
@ -266,6 +276,7 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa
* Update UI
*/
private fun updateUI() {
val bottomBar = binding.bottomBar
if (customField.type == CustomField.Type.LIST.uniqueIdentifier) {
bottomBar.animate().translationY(0f.px)
.setInterpolator(FastOutSlowInInterpolator())

@ -4,11 +4,12 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.realm.RealmModel
import kotlinx.android.synthetic.main.fragment_editable_data.*
import kotlinx.android.synthetic.main.fragment_editable_data.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.interfaces.Editable
import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.utils.CrashLogging
@ -87,6 +88,8 @@ open class EditableDataFragment : DataManagerFragment(), RowRepresentableDelegat
val liveDataType = this.model.liveDataType
val toolbar = this.view?.findViewById<Toolbar>(R.id.toolbar)
val data: RealmModel? = liveDataType.getData(this.getRealm(), this.model.primaryKey)
data?.let {
@ -96,13 +99,16 @@ open class EditableDataFragment : DataManagerFragment(), RowRepresentableDelegat
liveDataType.updateEntityLocalizedTitle(requireContext())
}
this.appBar.toolbar.title = title
toolbar?.title = title
deleteButtonShouldAppear = true
isUpdating = true
} ?: run {
this.appBar.toolbar.title = liveDataType.newEntityLocalizedTitle(requireContext())
toolbar?.title = liveDataType.newEntityLocalizedTitle(requireContext())
}
val recyclerView = this.view?.findViewById<RecyclerView>(R.id.recyclerView) ?: throw
PAIllegalStateException("recyclerView not found")
val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply {
setHasFixedSize(true)
@ -112,7 +118,7 @@ open class EditableDataFragment : DataManagerFragment(), RowRepresentableDelegat
val dataSource = getDataSource()
this.rowRepresentableAdapter = RowRepresentableAdapter(getDataSource(), this)
//this.rowRepresentableAdapter.setHasStableIds(true)
this.recyclerView.adapter = rowRepresentableAdapter
recyclerView.adapter = rowRepresentableAdapter
// When creating an object, open automatically the keyboard for the first row
if (!deleteButtonShouldAppear && shouldOpenKeyboard) {

@ -9,12 +9,12 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import kotlinx.android.synthetic.main.fragment_player.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentPlayerBinding
import net.pokeranalytics.android.model.realm.Comment
import net.pokeranalytics.android.model.realm.Player
import net.pokeranalytics.android.ui.activity.ColorPickerActivity
@ -22,7 +22,6 @@ import net.pokeranalytics.android.ui.activity.components.MediaActivity
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.extensions.showAlertDialog
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.RowViewType
@ -46,11 +45,14 @@ class PlayerDataFragment : EditableDataFragment(), StaticRowRepresentableDataSou
private var mediaActivity: MediaActivity? = null
private var _binding: FragmentPlayerBinding? = null
private val binding get() = _binding!!
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)
shouldOpenKeyboard = false
return inflater.inflate(R.layout.fragment_player, container, false)
_binding = FragmentPlayerBinding.inflate(inflater, container, false)
return binding.root
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@ -68,6 +70,11 @@ class PlayerDataFragment : EditableDataFragment(), StaticRowRepresentableDataSou
initUI()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
/**
* Init UI
*/
@ -80,7 +87,7 @@ class PlayerDataFragment : EditableDataFragment(), StaticRowRepresentableDataSou
onRowSelected(0, PlayerRow.NAME)
}
addComment.setOnClickListener {
binding.addComment.setOnClickListener {
val comment = player.addComment()
rowRepresentableAdapter.notifyDataSetChanged()
onRowSelected(-1, comment)

@ -11,8 +11,8 @@ import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.Realm
import io.realm.RealmResults
import kotlinx.android.synthetic.main.fragment_data_list.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentDataListBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.interfaces.Deletable
@ -44,6 +44,9 @@ open class DataListFragment : DeletableItemFragment(), RowRepresentableDelegate
private var menu: Menu? = null
private var searchView: SearchView? = null
private var _binding: FragmentDataListBinding? = null
private val binding get() = _binding!!
open fun retrieveItems(realm: Realm): RealmResults<out Deletable> {
return realm.sorted(this.model.identifiableClass,
editableOnly = true,
@ -56,7 +59,8 @@ open class DataListFragment : DeletableItemFragment(), RowRepresentableDelegate
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_data_list, container, false)
_binding = FragmentDataListBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -65,6 +69,11 @@ open class DataListFragment : DeletableItemFragment(), RowRepresentableDelegate
initUI()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
fun initData() {
val itemIds = this.model.itemIds
@ -106,14 +115,14 @@ open class DataListFragment : DeletableItemFragment(), RowRepresentableDelegate
val itemTouchHelper = ItemTouchHelper(swipeToDelete)
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = dataListAdapter
itemTouchHelper.attachToRecyclerView(this)
}
this.addButton.setOnClickListener {
binding.addButton.setOnClickListener {
EditableDataActivity.newInstanceForResult(this,
dataType = this.model.dataType,
@ -123,13 +132,13 @@ open class DataListFragment : DeletableItemFragment(), RowRepresentableDelegate
}
this.addButton.isVisible = this.model.showAddButton
binding.addButton.isVisible = this.model.showAddButton
}
override fun onResume() {
super.onResume()
this.recyclerView?.adapter?.notifyDataSetChanged()
binding.recyclerView.adapter?.notifyDataSetChanged()
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {

@ -10,13 +10,12 @@ import androidx.core.view.isVisible
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import com.android.billingclient.api.Purchase
import com.google.android.material.tabs.TabLayout
import com.google.firebase.crashlytics.FirebaseCrashlytics
import io.realm.RealmModel
import io.realm.RealmResults
import io.realm.Sort
import io.realm.kotlin.where
import kotlinx.android.synthetic.main.fragment_feed.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentFeedBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.interfaces.Editable
@ -105,6 +104,9 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate, PurchaseLis
}
private var _binding: FragmentFeedBinding? = null
private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppGuard.registerListener(this)
@ -114,9 +116,10 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate, PurchaseLis
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
): View {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_feed, container, false)
_binding = FragmentFeedBinding.inflate(inflater, container, false)
return binding.root
}
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo?) {
@ -219,6 +222,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate, PurchaseLis
override fun onDestroyView() {
super.onDestroyView()
realmTransactions.removeAllChangeListeners()
_binding = null
}
override fun onRowSelected(position: Int, row: RowRepresentable, tag: Int) {
@ -250,43 +254,43 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate, PurchaseLis
this.sessionAdapter = FeedSessionRowRepresentableAdapter(getRealm(), this)
registerForContextMenu(this.menuRecyclerView)
registerForContextMenu(binding.menuRecyclerView)
val messageToShow: Preferences.FeedMessage? =
Preferences.feedMessageToShow(requireContext())
if (messageToShow != null) {
messageBox.isVisible = true
message.text = getString(messageToShow.resId)
binding.messageBox.isVisible = true
binding.message.text = getString(messageToShow.resId)
messageToShow.actionResId?.let {
messageBoxAction.text = requireContext().getString(it)
binding.messageBoxAction.text = requireContext().getString(it)
messageToShow.action(requireContext())?.let { action ->
messageBoxAction.setOnClickListener { view ->
binding.messageBoxAction.setOnClickListener { view ->
action.invoke(view)
hideMessageBox(messageToShow)
}
}
} ?: run {
messageBoxAction.visibility = View.GONE
binding.messageBoxAction.visibility = View.GONE
}
messageBoxDismiss.text = requireContext().getString(messageToShow.dismissResId)
messageBoxDismiss.setOnClickListener {
binding.messageBoxDismiss.text = requireContext().getString(messageToShow.dismissResId)
binding.messageBoxDismiss.setOnClickListener {
hideMessageBox(messageToShow)
}
} else {
messageBox.isVisible = false
binding.messageBox.isVisible = false
}
val viewManager = SmoothScrollLinearLayoutManager(requireContext())
menuRecyclerView.apply {
binding.menuRecyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
}
// Add button
addButton.setOnClickListener {
binding.addButton.setOnClickListener {
activity?.let {
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(it)
val intent = Intent(requireContext(), NewDataMenuActivity::class.java)
@ -295,7 +299,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate, PurchaseLis
}
// Tabs
tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
binding.tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
when (tab.position) {
Tab.SESSIONS.ordinal -> {
@ -318,7 +322,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate, PurchaseLis
}
})
this.subscribe.setOnClickListener {
binding.subscribe.setOnClickListener {
if (!AppGuard.isProUser) {
BillingActivity.newInstanceForResult(this, false)
} else {
@ -330,15 +334,16 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate, PurchaseLis
}
private fun showSubscriptionButton() {
this.subscribe.isVisible = !AppGuard.isProUser
this.binding.subscribe.isVisible = !AppGuard.isProUser
}
private fun hideMessageBox(message: Preferences.FeedMessage) {
Preferences.setStopShowingMessage(message, requireContext())
val messageBox = binding.messageBox
messageBox.animate().translationY(messageBox.height.toFloat())
.setInterpolator(FastOutSlowInInterpolator())
.withEndAction { messageBox?.isVisible = false }
.withEndAction { messageBox.isVisible = false }
.start()
}
@ -553,7 +558,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate, PurchaseLis
private fun selectTab(tab: Tab) {
this.currentTab = tab
this.tabs.getTabAt(tab.ordinal)?.select()
this.binding.tabs.getTabAt(tab.ordinal)?.select()
setAdapter()
}
@ -564,9 +569,9 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate, PurchaseLis
private fun setAdapter() {
when (this.currentTab) {
Tab.SESSIONS -> menuRecyclerView.adapter = sessionAdapter
Tab.TRANSACTIONS -> menuRecyclerView.adapter = transactionAdapter
Tab.HAND_HISTORY -> menuRecyclerView.adapter = handHistoryAdapter
Tab.SESSIONS -> binding.menuRecyclerView.adapter = sessionAdapter
Tab.TRANSACTIONS -> binding.menuRecyclerView.adapter = transactionAdapter
Tab.HAND_HISTORY -> binding.menuRecyclerView.adapter = handHistoryAdapter
}
}

@ -11,13 +11,14 @@ import io.realm.RealmQuery
import io.realm.RealmResults
import io.realm.Sort
import io.realm.kotlin.where
import kotlinx.android.synthetic.main.row_feed_session.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.adapter.BindableHolder
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.SessionRowView
import net.pokeranalytics.android.util.extensions.getMonthAndYear
import timber.log.Timber
import java.util.*
@ -74,16 +75,17 @@ class FeedSessionRowRepresentableAdapter(
*/
inner class RowSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
private var sessionRow: SessionRowView = itemView.findViewById(R.id.sessionRow)
fun bind(position: Int, row: Session?, adapter: FeedSessionRowRepresentableAdapter) {
itemView.sessionRow.setData(row as Session)
this.sessionRow.setData(row as Session)
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.sessionRow.setOnClickListener(listener)
this.sessionRow.setOnClickListener(listener)
itemView.sessionRow.setOnLongClickListener {
this.sessionRow.setOnLongClickListener {
adapter.delegate?.onRowLongClick(itemView, row, adapterPosition)
return@setOnLongClickListener true
}

@ -6,12 +6,12 @@ import android.view.ViewGroup
import androidx.appcompat.widget.AppCompatTextView
import androidx.recyclerview.widget.RecyclerView
import io.realm.RealmResults
import kotlinx.android.synthetic.main.row_transaction.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Transaction
import net.pokeranalytics.android.ui.adapter.BindableHolder
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.TransactionRowView
import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.extensions.getMonthAndYear
import java.util.*
@ -42,14 +42,15 @@ class FeedTransactionRowRepresentableAdapter(
*/
inner class RowTransactionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
private var transactionRow: TransactionRowView = itemView.findViewById(R.id.transactionRow)
fun bind(position: Int, row: Transaction?, adapter: FeedTransactionRowRepresentableAdapter) {
itemView.transactionRow.setData(row as Transaction)
this.transactionRow.setData(row as Transaction)
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.transactionRow.setOnClickListener(listener)
this.transactionRow.setOnClickListener(listener)
}
}

@ -9,14 +9,14 @@ import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.ViewAnimationUtils
import kotlinx.android.synthetic.main.activity_new_data.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.ActivityNewDataBinding
import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.extensions.px
import kotlin.math.max
class NewDataMenuActivity : BaseActivity() {
@ -36,6 +36,8 @@ class NewDataMenuActivity : BaseActivity() {
private var menuWillBeHidden = false
private val fabSize = 48.px
private lateinit var binding: ActivityNewDataBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -43,7 +45,9 @@ class NewDataMenuActivity : BaseActivity() {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
setContentView(R.layout.activity_new_data)
binding = ActivityNewDataBinding.inflate(layoutInflater)
setContentView(binding.root)
initUI()
}
@ -63,27 +67,27 @@ class NewDataMenuActivity : BaseActivity() {
overridePendingTransition(0, 0)
container.viewTreeObserver.addOnGlobalLayoutListener {
binding.container.viewTreeObserver.addOnGlobalLayoutListener {
showMenu()
}
newCashGame.setOnClickListener {
binding.newCashGame.setOnClickListener {
finishWithResult(0)
}
newTournament.setOnClickListener {
binding.newTournament.setOnClickListener {
finishWithResult(1)
}
newTransaction.setOnClickListener {
binding.newTransaction.setOnClickListener {
finishWithResult(2)
}
new_hand_history.setOnClickListener {
binding.newHandHistory.setOnClickListener {
finishWithResult(3)
}
container.setOnClickListener {
binding.container.setOnClickListener {
hideMenu()
}
}
@ -112,9 +116,10 @@ class NewDataMenuActivity : BaseActivity() {
*/
private fun showMenu() {
val menuContainer = binding.menuContainer
val cx = menuContainer.measuredWidth - fabSize / 2
val cy = menuContainer.measuredHeight - fabSize / 2
val finalRadius = Math.max(menuContainer.width, menuContainer.height)
val finalRadius = max(menuContainer.width, menuContainer.height)
val anim = ViewAnimationUtils.createCircularReveal(menuContainer, cx, cy, 0f, finalRadius.toFloat())
anim.duration = 150
@ -132,6 +137,7 @@ class NewDataMenuActivity : BaseActivity() {
}
menuWillBeHidden = true
val menuContainer = binding.menuContainer
val cx = menuContainer.measuredWidth - fabSize / 2
val cy = menuContainer.measuredHeight - fabSize / 2
val initialRadius = menuContainer.width

@ -6,9 +6,8 @@ import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_filter_details.*
import kotlinx.android.synthetic.main.fragment_filter_details.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentFilterDetailsBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
@ -30,6 +29,9 @@ open class FilterDetailsFragment : RealmFragment(), RowRepresentableDelegate {
private lateinit var rowRepresentableAdapter: RowRepresentableAdapter
private var _binding: FragmentFilterDetailsBinding? = null
private val binding get() = _binding!!
companion object {
fun newInstance(categoryRow: FilterCategoryRow): FilterDetailsFragment {
@ -44,7 +46,8 @@ open class FilterDetailsFragment : RealmFragment(), RowRepresentableDelegate {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_filter_details, container, false)
_binding = FragmentFilterDetailsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -58,6 +61,11 @@ open class FilterDetailsFragment : RealmFragment(), RowRepresentableDelegate {
saveData()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
/**
* Init UI
*/
@ -65,11 +73,11 @@ open class FilterDetailsFragment : RealmFragment(), RowRepresentableDelegate {
setDisplayHomeAsUpEnabled(true)
this.appBar.toolbar.title = getString(R.string.filter)
this.binding.toolbar.title = getString(R.string.filter)
val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
}
@ -95,10 +103,10 @@ open class FilterDetailsFragment : RealmFragment(), RowRepresentableDelegate {
Timber.d(">> Filter = ${this.activityModel.currentFilter}")
Timber.d("selectedRow = ${this.activityModel.selectedCategoryRow}")
this.appBar.toolbar.title = this.activityModel.selectedCategoryRow?.localizedTitle(requireContext())
this.binding.toolbar.title = this.activityModel.selectedCategoryRow?.localizedTitle(requireContext())
this.rowRepresentableAdapter = RowRepresentableAdapter(this.model, this)
this.recyclerView.adapter = rowRepresentableAdapter
this.binding.recyclerView.adapter = rowRepresentableAdapter
}
override fun onRowSelected(position: Int, row: RowRepresentable, tag: Int) {

@ -8,11 +8,8 @@ import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.chip.Chip
import kotlinx.android.synthetic.main.fragment_editable_data.appBar
import kotlinx.android.synthetic.main.fragment_editable_data.recyclerView
import kotlinx.android.synthetic.main.fragment_filters.*
import kotlinx.android.synthetic.main.fragment_filters.view.toolbar
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentFiltersBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.realm.Filter
@ -44,9 +41,13 @@ open class FiltersFragment : RealmFragment(), RowRepresentableDelegate {
private var showMostUsedFiltersLayout = true
private var _binding: FragmentFiltersBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_filters, container, false)
_binding = FragmentFiltersBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -102,6 +103,11 @@ open class FiltersFragment : RealmFragment(), RowRepresentableDelegate {
return true
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
/**
* Init UI
*/
@ -109,20 +115,20 @@ open class FiltersFragment : RealmFragment(), RowRepresentableDelegate {
setDisplayHomeAsUpEnabled(true)
this.appBar.toolbar.title = getString(R.string.filter)
this.binding.toolbar.title = getString(R.string.filter)
val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply {
this.binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
}
moreFilters.setOnClickListener {
this.binding.moreFilters.setOnClickListener {
LiveData.FILTER.subType = this.model.filterableType?.uniqueIdentifier
FiltersListActivity.newSelectInstance(this, false)
}
mostUsedFiltersLayout.isVisible = showMostUsedFiltersLayout
this.binding.mostUsedFiltersLayout.isVisible = showMostUsedFiltersLayout
}
/**
@ -133,7 +139,7 @@ open class FiltersFragment : RealmFragment(), RowRepresentableDelegate {
this.model.init(getRealm())
this.rowRepresentableAdapter = RowRepresentableAdapter(this.model, this)
this.recyclerView.adapter = rowRepresentableAdapter
this.binding.recyclerView.adapter = rowRepresentableAdapter
}
@ -157,11 +163,11 @@ open class FiltersFragment : RealmFragment(), RowRepresentableDelegate {
val currentFilterId = Preferences.getActiveFilterId(requireContext())
if (this.model.isUpdating || filters.isEmpty() || (filters.size == 1 && filters.first()?.id == currentFilterId)) {
mostUsedFiltersLayout.visibility = View.GONE
this.binding.mostUsedFiltersLayout.visibility = View.GONE
return
}
mostUsedFilters.removeAllViews()
this.binding.mostUsedFilters.removeAllViews()
filters.forEach { filter ->
if (nbChips < MOST_USED_FILTERS_DISPLAYED) {
@ -185,7 +191,7 @@ open class FiltersFragment : RealmFragment(), RowRepresentableDelegate {
finishActivityWithResult("")
}
}
mostUsedFilters.addView(chip)
this.binding.mostUsedFilters.addView(chip)
nbChips++
}
}
@ -249,7 +255,7 @@ open class FiltersFragment : RealmFragment(), RowRepresentableDelegate {
fun updateMostUsedFiltersVisibility(visible: Boolean) {
Timber.d("updateMostUsedFiltersVisibility: $visible")
showMostUsedFiltersLayout = visible
mostUsedFiltersLayout?.isVisible = visible
this.binding.mostUsedFiltersLayout.isVisible = visible
}
}

@ -4,9 +4,8 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment
import net.pokeranalytics.android.ui.modules.filter.FilterHandler.Companion.INTENT_FILTER_UPDATE_FILTER_UI
import net.pokeranalytics.android.ui.modules.datalist.DataListFragment
import net.pokeranalytics.android.ui.modules.filter.FilterHandler.Companion.INTENT_FILTER_UPDATE_FILTER_UI
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.util.Preferences

@ -3,24 +3,13 @@ package net.pokeranalytics.android.ui.modules.handhistory.editor
import android.content.res.ColorStateList
import android.text.InputType
import android.view.*
import android.widget.Button
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.*
import androidx.appcompat.widget.AppCompatButton
import androidx.core.view.isEmpty
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.chip.Chip
import kotlinx.android.synthetic.main.row_hand_action.view.*
import kotlinx.android.synthetic.main.row_hand_action_read.view.*
import kotlinx.android.synthetic.main.row_hand_cards.view.*
import kotlinx.android.synthetic.main.row_hand_player_summary.view.*
import kotlinx.android.synthetic.main.row_hhsettings_player_setup.view.*
import kotlinx.android.synthetic.main.row_hhsettings_player_setup.view.position_button
import kotlinx.android.synthetic.main.row_hhsettings_player_setup.view.ps_hand_layout
import kotlinx.android.synthetic.main.row_hhsettings_player_setup_read.view.*
import kotlinx.android.synthetic.main.row_hhsettings_straddle.view.*
import kotlinx.android.synthetic.main.row_recycler.view.*
import com.google.android.material.internal.FlowLayout
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.handhistory.Position
@ -69,9 +58,9 @@ enum class HandRowType(var layoutRes: Int) : ViewIdentifier, RowRepresentable {
override val bottomSheetType: BottomSheetType
get() {
return when(this) {
PLAYER_NUMBER -> BottomSheetType.GRID
COMMENT -> BottomSheetType.EDIT_TEXT_MULTI_LINES
ANTE -> BottomSheetType.NUMERIC_TEXT
PLAYER_NUMBER -> BottomSheetType.GRID
COMMENT -> BottomSheetType.EDIT_TEXT_MULTI_LINES
ANTE -> BottomSheetType.NUMERIC_TEXT
else -> BottomSheetType.NONE
}
}
@ -79,11 +68,11 @@ enum class HandRowType(var layoutRes: Int) : ViewIdentifier, RowRepresentable {
override val resId: Int?
get() {
return when(this) {
PLAYER_NUMBER -> R.string.number_of_players
COMMENT -> R.string.comment
ANTE -> R.string.ante
BIG_BLIND_ANTE, BIG_BLIND_ANTE_READ -> R.string.bb_ante_option
SETTINGS_HEADER -> R.string.settings
PLAYER_NUMBER -> R.string.number_of_players
COMMENT -> R.string.comment
ANTE -> R.string.ante
BIG_BLIND_ANTE, BIG_BLIND_ANTE_READ -> R.string.bb_ante_option
SETTINGS_HEADER -> R.string.settings
else -> null
}
}
@ -91,8 +80,8 @@ enum class HandRowType(var layoutRes: Int) : ViewIdentifier, RowRepresentable {
override val imageRes: Int?
get() {
return when(this) {
COMMENT -> R.drawable.picto_comment
SETTINGS_HEADER -> R.drawable.ic_settings
COMMENT -> R.drawable.picto_comment
SETTINGS_HEADER -> R.drawable.ic_settings
else -> null
}
}
@ -103,8 +92,9 @@ enum class HandRowType(var layoutRes: Int) : ViewIdentifier, RowRepresentable {
}
class EditorAdapter(
override var dataSource: RowRepresentableDataSource,
override var delegate: RowRepresentableDelegate? = null) :
override var dataSource: RowRepresentableDataSource,
override var delegate: RowRepresentableDelegate? = null
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>(),
RecyclerAdapter {
@ -116,21 +106,21 @@ class EditorAdapter(
val rowType: HandRowType = HandRowType.values()[viewType]
val layout = LayoutInflater.from(parent.context).inflate(rowType.layoutRes, parent, false)
return when (rowType) {
HandRowType.DEFAULT -> RowViewHolder(layout)
HandRowType.HEADER -> RowViewHolder(layout)
HandRowType.SETTINGS_HEADER -> RowViewHolder(layout)
HandRowType.ACTION -> RowActionHolder(layout)
HandRowType.STREET -> RowStreetHolder(layout)
HandRowType.PLAYER_SUMMARY -> RowPlayerSummaryHolder(layout)
HandRowType.STRADDLE -> RowStraddleHolder(layout)
HandRowType.PLAYER_SETUP -> RowPlayerSetupHolder(layout)
HandRowType.PLAYER_SETUP_READ -> RowReadOnlyPlayerSetupHolder(layout)
HandRowType.COMMENT -> RowViewHolder(layout)
HandRowType.ACTION_READ -> RowActionReadHolder(layout)
HandRowType.HERO_POSITION, HandRowType.PLAYER_POSITION -> RowPositionHolder(layout)
HandRowType.PLAYER_NUMBER,
HandRowType.ANTE,
HandRowType.BIG_BLIND_ANTE, HandRowType.BIG_BLIND_ANTE_READ -> RowViewHolder(layout)
HandRowType.DEFAULT -> RowViewHolder(layout)
HandRowType.HEADER -> RowViewHolder(layout)
HandRowType.SETTINGS_HEADER -> RowViewHolder(layout)
HandRowType.ACTION -> RowActionHolder(layout)
HandRowType.STREET -> RowStreetHolder(layout)
HandRowType.PLAYER_SUMMARY -> RowPlayerSummaryHolder(layout)
HandRowType.STRADDLE -> RowStraddleHolder(layout)
HandRowType.PLAYER_SETUP -> RowPlayerSetupHolder(layout)
HandRowType.PLAYER_SETUP_READ -> RowReadOnlyPlayerSetupHolder(layout)
HandRowType.COMMENT -> RowViewHolder(layout)
HandRowType.ACTION_READ -> RowActionReadHolder(layout)
HandRowType.HERO_POSITION, HandRowType.PLAYER_POSITION -> RowPositionHolder(layout)
HandRowType.PLAYER_NUMBER,
HandRowType.ANTE,
HandRowType.BIG_BLIND_ANTE, HandRowType.BIG_BLIND_ANTE_READ -> RowViewHolder(layout)
}
}
@ -180,15 +170,27 @@ class EditorAdapter(
this.currentPosition = position
}
protected fun configureEditTexts(index: Int, position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
protected fun configureEditTexts(
index: Int,
position: Int,
row: RowRepresentable,
adapter: RecyclerAdapter
) {
this.configureEditTexts(index..index, position, row, adapter)
}
private fun configureEditTexts(tagRange: IntRange, position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
private fun configureEditTexts(
tagRange: IntRange,
position: Int,
row: RowRepresentable,
adapter: RecyclerAdapter
) {
tagRange.forEach { tag ->
val editText = itemView.findViewWithTag<EditText>(tag) ?: throw PAIllegalStateException("Edit Text not found for tag: $tag, class: $this")
val editText = itemView.findViewWithTag<EditText>(tag) ?: throw PAIllegalStateException(
"Edit Text not found for tag: $tag, class: $this"
)
// hides soft input view
editText.setTextIsSelectable(true)
@ -229,7 +231,9 @@ class EditorAdapter(
}
protected fun configureTextView(tag: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
val textView = itemView.findViewWithTag<TextView>(tag) ?: throw PAIllegalStateException("TextView not found for tag: $tag, class: $this")
val textView = itemView.findViewWithTag<TextView>(tag) ?: throw PAIllegalStateException(
"TextView not found for tag: $tag, class: $this"
)
textView.text = adapter.dataSource.charSequenceForRow(row, itemView.context, tag)
}
@ -287,7 +291,11 @@ class EditorAdapter(
return itemView.findViewWithTag(tag)
}
protected fun configurePlayerImage(playerImageView: PlayerImageView, position: Int, row: RowRepresentable) {
protected fun configurePlayerImage(
playerImageView: PlayerImageView,
position: Int,
row: RowRepresentable
) {
// Player
val listener = View.OnClickListener {
@ -359,6 +367,8 @@ class EditorAdapter(
}
inner class RowStraddleHolder(itemView: View) : RowHandHolder(itemView) {
private var container: ViewGroup = itemView.findViewById(R.id.container)
private var positionsChipGroup: FlowLayout = itemView.findViewById(R.id.positionsChipGroup)
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
super.onBind(position, row, adapter)
@ -366,10 +376,14 @@ class EditorAdapter(
val straddleRow = row as StraddleRowRepresentable
adapter.dataSource.backgroundColor(position, row)?.let { color ->
itemView.findViewById<ViewGroup>(R.id.container)?.setBackgroundColor(itemView.context.getColor(color))
this.container.setBackgroundColor(
itemView.context.getColor(
color
)
)
}
itemView.positionsChipGroup.removeAllViews()
this.positionsChipGroup.removeAllViews()
straddleRow.positions.forEach { pos ->
val chip = Chip(itemView.context)
@ -388,20 +402,21 @@ class EditorAdapter(
}
adapter.delegate?.onRowValueChanged(straddleRow.selectedPositions, row)
}
itemView.positionsChipGroup.addView(chip)
this.positionsChipGroup.addView(chip)
}
}
}
inner class RowPositionHolder(itemView: View) : RowHandHolder(itemView) {
private var recycler: RecyclerView = itemView.findViewById(R.id.recycler)
private var positionAdapter: PositionAdapter = PositionAdapter()
private var positionViewManager: LinearLayoutManager =
LinearLayoutManager(itemView.context, RecyclerView.HORIZONTAL, false)
init {
itemView.recycler.apply {
this.recycler.apply {
setHasFixedSize(true)
layoutManager = positionViewManager
adapter = positionAdapter
@ -411,7 +426,11 @@ class EditorAdapter(
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
super.onBind(position, row, adapter)
this.positionAdapter.positions = adapter.dataSource.contentForRow(row, itemView.context, Position::class)
this.positionAdapter.positions = adapter.dataSource.contentForRow(
row,
itemView.context,
Position::class
)
this.positionAdapter.setOnClickListener { pos ->
adapter.delegate?.onRowValueChanged(pos, row)
this.positionAdapter.notifyDataSetChanged()
@ -427,26 +446,33 @@ class EditorAdapter(
inner class RowActionReadHolder(itemView: View) : RowHandHolder(itemView) {
init {
itemView.player_image_rhar.tag = ActionReadRow.Tag.PLAYER.ordinal
itemView.stackText.tag = ActionReadRow.Tag.STACK.ordinal
private var playerImage: PlayerImageView = itemView.findViewById(R.id.player_image_rhar)
private var stackText: TextView = itemView.findViewById(R.id.stackText)
private var playersText: TextView = itemView.findViewById(R.id.playersText)
private var actionText: TextView = itemView.findViewById(R.id.actionText)
private var actionContainer: View = itemView.findViewById(R.id.action_container)
private var amountText: TextView = itemView.findViewById(R.id.amountText)
init {
playerImage.tag = ActionReadRow.Tag.PLAYER.ordinal
stackText.tag = ActionReadRow.Tag.STACK.ordinal
}
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
configurePlayerImage(itemView.player_image_rhar, position, row)
configurePlayerImage(this.playerImage, position, row)
val actionReadRow = row as ActionReadRow
itemView.playersText.text = actionReadRow.positions.joinToString(", ") { it.value }
this.playersText.text = actionReadRow.positions.joinToString(", ") { it.value }
actionReadRow.action?.let { type ->
itemView.actionText.text = type.localizedTitle(itemView.context)
this.actionText.text = type.localizedTitle(itemView.context)
val background = itemView.context.getDrawable(type.background)
itemView.action_container.background = background
this.actionContainer.background = background
}
itemView.amountText.text = actionReadRow.amount?.formatted
itemView.stackText.text = actionReadRow.stack?.formatted
this.amountText.text = actionReadRow.amount?.formatted
this.stackText.text = actionReadRow.stack?.formatted
}
}
@ -456,36 +482,42 @@ class EditorAdapter(
*/
inner class RowActionHolder(itemView: View) : RowHandHolder(itemView) {
init {
itemView.player_image_rha.tag = ComputedAction.Tag.PLAYER.ordinal
itemView.actionButton.tag = ComputedAction.Tag.ACTION.ordinal
itemView.amountEditText.tag = ComputedAction.Tag.AMOUNT.ordinal
private var playerImage: PlayerImageView = itemView.findViewById(R.id.player_image_rha)
private var actionButton: AppCompatButton = itemView.findViewById(R.id.actionButton)
private var amountEditText: EditText = itemView.findViewById(R.id.amountEditText)
private var positionButton: AppCompatButton = itemView.findViewById(R.id.positionButton)
init {
this.playerImage.tag = ComputedAction.Tag.PLAYER.ordinal
this.actionButton.tag = ComputedAction.Tag.ACTION.ordinal
this.amountEditText.tag = ComputedAction.Tag.AMOUNT.ordinal
// Action
setOnClickListener(itemView.actionButton)
setOnClickListener(this.actionButton)
// Amount
itemView.findViewById<EditText>(R.id.amountEditText)?.let { amountEditText ->
this.amountEditText.let { amountEditText ->
amountEditText.inputType = InputType.TYPE_NUMBER_FLAG_DECIMAL
amountEditText.isFocusableInTouchMode = true
amountEditText.inputType = InputType.TYPE_NUMBER_FLAG_DECIMAL
amountEditText.isFocusableInTouchMode = true
amountEditText.setOnTouchListener { _, event ->
amountEditText.setOnTouchListener { _, event ->
// Timber.d("=== event.action = ${event.action}")
if (event.action == MotionEvent.ACTION_UP) {
// Both are required, otherwise requestFocus() fails
amountEditText.isFocusable = true
amountEditText.isFocusableInTouchMode = true
// Timber.d("=== event.action = ${event.action}")
if (event.action == MotionEvent.ACTION_UP) {
// Both are required, otherwise requestFocus() fails
amountEditText.isFocusable = true
amountEditText.isFocusableInTouchMode = true
amountEditText.requestFocus()
amountEditText.requestFocus()
editTextSelected(amountEditText)
}
return@setOnTouchListener true
}
editTextSelected(amountEditText)
}
return@setOnTouchListener true
}
}
}
}
private fun positionColor(isFocused: Boolean) : Int {
@ -498,17 +530,17 @@ class EditorAdapter(
val computedAction = row as ComputedAction
configurePlayerImage(itemView.player_image_rha, position, row)
configurePlayerImage(this.playerImage, position, row)
// Position
itemView.findViewById<Button>(R.id.positionButton)?.let { button ->
this.positionButton.let { button ->
button.text = computedAction.position.value
// button.setBackgroundColor(color(computedAction.isHero))
button.backgroundTintList = ColorStateList.valueOf(positionColor(computedAction.isHero))
}
// Action
itemView.findViewById<Button>(R.id.actionButton)?.let { actionButton ->
this.actionButton.let { actionButton ->
actionButton.isEnabled = adapter.dataSource.isEnabled(row, actionButton.tag as Int)
val selected = adapter.dataSource.isSelected(position, row, actionButton.tag as Int)
@ -523,7 +555,7 @@ class EditorAdapter(
}
// Amount
itemView.findViewById<EditText>(R.id.amountEditText)?.let { amountEditText ->
this.amountEditText.let { amountEditText ->
val tag = amountEditText.tag as Int
configureEditTexts(tag, position, row, adapter)
}
@ -536,14 +568,15 @@ class EditorAdapter(
* Display a hand street
*/
inner class RowStreetHolder(itemView: View) : RowHandHolder(itemView) {
private var cardsLayout: LinearLayout = itemView.findViewById(R.id.cardsLayout)
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
super.onBind(position, row, adapter)
val streetCardsRow = row as StreetCardsRow
itemView.cardsLayout.tag = streetCardsRow.street.ordinal
this.cardsLayout.tag = streetCardsRow.street.ordinal
configureCardsLayout(itemView.cardsLayout, true)
configureCardsLayout(this.cardsLayout, true)
}
@ -553,10 +586,12 @@ class EditorAdapter(
* Display a hand action
*/
inner class RowPlayerSummaryHolder(itemView: View) : RowHandHolder(itemView) {
private var hpsPlayerImage: PlayerImageView = itemView.findViewById(R.id.hps_player_image)
private var handLayout: LinearLayout = itemView.findViewById(R.id.handLayout)
init {
itemView.hps_player_image.tag = PlayerCardsRow.Tag.PLAYER.ordinal
itemView.handLayout.tag = PlayerCardsRow.Tag.CARDS.ordinal
this.hpsPlayerImage.tag = PlayerCardsRow.Tag.PLAYER.ordinal
this.handLayout.tag = PlayerCardsRow.Tag.CARDS.ordinal
}
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
@ -571,18 +606,20 @@ class EditorAdapter(
positionButton.setBackgroundColor(color(playerCardView.isHero))
}
configurePlayerImage(itemView.hps_player_image, position, row)
configurePlayerImage(this.hpsPlayerImage, position, row)
configureCardsLayout(itemView.handLayout as LinearLayout, false)
configureCardsLayout(this.handLayout, false)
}
}
abstract inner class AbstractRowPlayerSetup(itemView: View) : RowHandHolder(itemView) {
private var psHandLayout: LinearLayout = itemView.findViewById(R.id.ps_hand_layout)
private var positionButton: AppCompatButton = itemView.findViewById(R.id.position_button)
protected var delegate: RowRepresentableDelegate? = null
init {
itemView.ps_hand_layout.tag = PlayerSetupRow.Tag.HAND.ordinal
this.psHandLayout.tag = PlayerSetupRow.Tag.HAND.ordinal
}
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
@ -591,22 +628,28 @@ class EditorAdapter(
this.delegate = adapter.delegate
// Position Button
itemView.position_button.text = adapter.dataSource.charSequenceForRow(row, itemView.context, PlayerSetupRow.Tag.POSITION.ordinal)
this.positionButton.text = adapter.dataSource.charSequenceForRow(
row,
itemView.context,
PlayerSetupRow.Tag.POSITION.ordinal
)
val positionalRow = row as PositionalRow
itemView.position_button.backgroundTintList = ColorStateList.valueOf(color(positionalRow.isHero))
this.positionButton.backgroundTintList = ColorStateList.valueOf(color(positionalRow.isHero))
configureCardsLayout(itemView.ps_hand_layout as LinearLayout, false)
configureCardsLayout(this.psHandLayout, false)
}
}
inner class RowReadOnlyPlayerSetupHolder(itemView: View) : AbstractRowPlayerSetup(itemView) {
private var psPlayerImage: PlayerImageView = itemView.findViewById(R.id.ps_player_image)
private var stackTextView: TextView = itemView.findViewById(R.id.stack_text_view)
init {
itemView.ps_player_image.tag = PlayerSetupRow.Tag.PLAYER.ordinal
itemView.stack_text_view.tag = PlayerSetupRow.Tag.STACK.ordinal
this.psPlayerImage.tag = PlayerSetupRow.Tag.PLAYER.ordinal
this.stackTextView.tag = PlayerSetupRow.Tag.STACK.ordinal
}
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
@ -615,23 +658,27 @@ class EditorAdapter(
configureTextView(PlayerSetupRow.Tag.STACK.ordinal, row, adapter)
// Player
configurePlayerImage(itemView.ps_player_image, position, row as PlayerSetupRow)
configurePlayerImage(this.psPlayerImage, position, row as PlayerSetupRow)
}
}
inner class RowPlayerSetupHolder(itemView: View) : AbstractRowPlayerSetup(itemView) {
private var playerImage: PlayerImageView = itemView.findViewById(R.id.player_image)
private var positionButton: AppCompatButton = itemView.findViewById(R.id.position_button)
private var psHandLayout: LinearLayout = itemView.findViewById(R.id.ps_hand_layout)
private var stackEditText: EditText = itemView.findViewById(R.id.stack_edit_text)
init {
itemView.player_image.tag = PlayerSetupRow.Tag.PLAYER.ordinal
itemView.position_button.tag = PlayerSetupRow.Tag.POSITION.ordinal
itemView.ps_hand_layout.tag = PlayerSetupRow.Tag.HAND.ordinal
itemView.stack_edit_text.tag = PlayerSetupRow.Tag.STACK.ordinal
this.playerImage.tag = PlayerSetupRow.Tag.PLAYER.ordinal
this.positionButton.tag = PlayerSetupRow.Tag.POSITION.ordinal
this.psHandLayout.tag = PlayerSetupRow.Tag.HAND.ordinal
this.stackEditText.tag = PlayerSetupRow.Tag.STACK.ordinal
itemView.stack_edit_text.inputType = InputType.TYPE_NUMBER_FLAG_DECIMAL
setClickListener(itemView.stack_edit_text)
setOnItemClickListener(itemView.position_button, false)
this.stackEditText.inputType = InputType.TYPE_NUMBER_FLAG_DECIMAL
setClickListener(this.stackEditText)
setOnItemClickListener(this.positionButton, false)
}
@ -639,7 +686,7 @@ class EditorAdapter(
super.onBind(position, row, adapter)
// Player
configurePlayerImage(itemView.player_image, position, row)
configurePlayerImage(this.playerImage, position, row)
configureEditTexts(PlayerSetupRow.Tag.STACK.ordinal, position, row, adapter)
}

@ -11,9 +11,8 @@ import android.view.animation.AccelerateDecelerateInterpolator
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import kotlinx.android.synthetic.main.fragment_hand_history.*
import kotlinx.android.synthetic.main.fragment_settings.recyclerView
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentHandHistoryBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.handhistory.Position
@ -68,6 +67,9 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
return this.model.isEdited
}
private var _binding: FragmentHandHistoryBinding? = null
private val binding get() = _binding!!
companion object {
fun newInstance(id: String? = null, configurationId: String? = null, attached: Boolean = false): EditorFragment {
@ -91,9 +93,10 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
}
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)
return inflater.inflate(R.layout.fragment_hand_history, container, false)
_binding = FragmentHandHistoryBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -137,7 +140,7 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
// }
// val itemTouchHelper = ItemTouchHelper(swipeToDelete)
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = SmoothScrollLinearLayoutManager(requireContext())
adapter = editorAdapter
@ -156,7 +159,7 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
// At first, the selection is defined before the holder is bound,
// so we retrieve the editText inputConnection once the recycler view has been rendered
this.recyclerView.viewTreeObserver.addOnGlobalLayoutListener {
this.binding.recyclerView.viewTreeObserver.addOnGlobalLayoutListener {
when (this.model.currentKeyboard) {
HHKeyboard.AMOUNT -> {
val selection = this.model.currentSelection
@ -168,7 +171,7 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
}
initKeyboardDefaultHeight()
this.keyboard.keyboardListener = this
this.binding.keyboard.keyboardListener = this
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
@ -227,6 +230,11 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
return true
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun showReplayer() {
(this.activity as HandHistoryActivity).showReplayer(this.model.handHistory.id)
}
@ -295,10 +303,10 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
val handRow = this.model.rowRepresentableForPosition(selection.index) as? HandHistoryRow
val holder =
recyclerView.findViewHolderForAdapterPosition(selection.index) as? EditorAdapter.RowHandHolder
binding.recyclerView.findViewHolderForAdapterPosition(selection.index) as? EditorAdapter.RowHandHolder
holder?.let {
val amountEditText = it.editTextForTag(selection.tag)
this.keyboard.setAmountEditText(
this.binding.keyboard.setAmountEditText(
amountEditText,
handRow?.amountForTag(this.model.handHistory, selection.tag)
)
@ -541,10 +549,10 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
*/
private fun configureActionKeyboard() {
val availableActions = this.model.availableActions()
this.keyboard.setAvailableAction(availableActions)
this.binding.keyboard.setAvailableAction(availableActions)
val positions = this.model.positionsToAct()
this.keyboard.setPositions(positions)
this.binding.keyboard.setPositions(positions)
}
/***
@ -579,7 +587,7 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
* We subtract 1 to give space and the ability to see the previously entered data
*/
private fun scrollToPosition(index: Int) {
this.recyclerView.smoothScrollToPosition(index - 1)
this.binding.recyclerView.smoothScrollToPosition(index - 1)
}
/***
@ -606,11 +614,11 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
*/
private fun showKeyboard(keyboard: HHKeyboard, endHandler: (() -> (Unit))? = null) {
val lp = this.kbTopGuideline.layoutParams as ConstraintLayout.LayoutParams
val lp = this.binding.kbTopGuideline.layoutParams as ConstraintLayout.LayoutParams
if (lp.guideEnd == 0) {
this.animateKeyboard(true, endHandler)
}
this.keyboard.show(keyboard)
this.binding.keyboard.show(keyboard)
}
/***
@ -631,11 +639,11 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
// set interpolator and updateListener to get the animated value
valueAnimator.addUpdateListener {
val lp = this.kbTopGuideline.layoutParams as ConstraintLayout.LayoutParams
val lp = this.binding.kbTopGuideline.layoutParams as ConstraintLayout.LayoutParams
// get the float value
lp.guideEnd = (it.animatedValue as Float).toInt()
// update layout params
this.kbTopGuideline.layoutParams = lp
this.binding.kbTopGuideline.layoutParams = lp
if (lp.guideEnd == end.toInt()) {
endHandler?.invoke()
@ -649,7 +657,7 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
* Starts by hiding the keyboard
*/
private fun initKeyboardDefaultHeight() {
val lp = this.kbTopGuideline.layoutParams as ConstraintLayout.LayoutParams
val lp = this.binding.kbTopGuideline.layoutParams as ConstraintLayout.LayoutParams
lp.guideEnd = 0
}

@ -8,8 +8,8 @@ import android.widget.PopupWindow
import android.widget.Switch
import androidx.lifecycle.ViewModelProvider
import io.realm.Sort
import kotlinx.android.synthetic.main.fragment_replayer.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.databinding.FragmentReplayerBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
@ -38,6 +38,9 @@ class ReplayerFragment : RealmFragment() {
*/
private lateinit var model: ReplayerModel
private var _binding: FragmentReplayerBinding? = null
private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -47,9 +50,10 @@ class ReplayerFragment : RealmFragment() {
}
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)
return inflater.inflate(R.layout.fragment_replayer, container, false)
_binding = FragmentReplayerBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -79,6 +83,11 @@ class ReplayerFragment : RealmFragment() {
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun initData() {
val id = arguments?.getString(BundleKey.HAND_HISTORY_ID.value) ?: throw PAIllegalStateException("Attempt to start a replayer without hh id")
val hh = getRealm().findById<HandHistory>(id) ?: throw PAIllegalStateException("hh with id: $id not found")
@ -86,25 +95,25 @@ class ReplayerFragment : RealmFragment() {
}
private fun initUI() {
this.next_action.setOnClickListener {
this.binding.nextAction.setOnClickListener {
nextAction()
}
this.previous_action.setOnClickListener {
this.binding.previousAction.setOnClickListener {
previousAction()
}
this.next_hand.setOnClickListener {
this.binding.nextHand.setOnClickListener {
nextHand()
}
this.previous_hand.setOnClickListener {
this.binding.previousHand.setOnClickListener {
previousHand()
}
this.play_pause.setOnClickListener {
this.binding.playPause.setOnClickListener {
playOrPause()
}
this.speed.setOnClickListener {
this.binding.speed.setOnClickListener {
changeSpeed()
}
this.settings.setOnClickListener {
this.binding.settings.setOnClickListener {
openSettings()
}
@ -131,12 +140,12 @@ class ReplayerFragment : RealmFragment() {
private fun updateSpeedButtonText() {
val speedText = "${this.model.speedMultiplier.value}x"
this.speed.text = speedText
this.binding.speed.text = speedText
}
private fun loadHand(handHistory: HandHistory) {
val config = ReplayerAnimator(handHistory, false)
this.replayer.animator = config
this.binding.replayer.animator = config
this.model.animator = config
}
@ -164,18 +173,18 @@ class ReplayerFragment : RealmFragment() {
this.mainHandler.postDelayed(timerRunnable, 0L)
this.model.isPlaying = true
this.play_pause.setImageResource(R.drawable.ic_outline_pause)
this.binding.playPause.setImageResource(R.drawable.ic_outline_pause)
}
private fun pause() {
this.mainHandler.removeCallbacks(timerRunnable)
this.model.isPlaying = false
this.play_pause.setImageResource(R.drawable.ic_play_arrow)
this.binding.playPause.setImageResource(R.drawable.ic_play_arrow)
}
private fun nextAction() {
this.model.nextStep()
this.replayer.refresh()
this.binding.replayer.refresh()
if (this.model.isPlaying) {
this.mainHandler.postDelayed(timerRunnable, this.model.actionDelay)
@ -185,7 +194,7 @@ class ReplayerFragment : RealmFragment() {
private fun previousAction() {
this.model.previousStep()
this.replayer.refresh()
this.binding.replayer.refresh()
refreshPlayButtonIfNecessary()
}
@ -237,13 +246,13 @@ class ReplayerFragment : RealmFragment() {
switch.isChecked = Preferences.getShowVillainCards(requireContext())
switch.setOnCheckedChangeListener { _, isChecked ->
Preferences.setShowVillainCards(isChecked, requireContext())
this.replayer.refresh()
this.binding.replayer.refresh()
}
val popupWindow = PopupWindow(requireContext())
popupWindow.contentView = view
popupWindow.isFocusable = true
popupWindow.showAsDropDown(this.settings, 0, -300)
popupWindow.showAsDropDown(this.binding.settings, 0, -300)
}

@ -2,10 +2,10 @@ package net.pokeranalytics.android.ui.modules.handhistory.views
import android.content.Context
import android.view.LayoutInflater
import android.widget.ImageButton
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.view_hand_keyboard_action.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.handhistory.Position
@ -26,10 +26,15 @@ class KeyboardActionView(context: Context) : AbstractKeyboardView(context),
private var availableActions: Set<Action.Type> = setOf()
private var recyclerView: RecyclerView
private var closeButton: ImageButton
init {
LayoutInflater.from(context)
val view = LayoutInflater.from(context)
.inflate(R.layout.view_hand_keyboard_action, this, true)
this.recyclerView = view.findViewById<RecyclerView>(R.id.recyclerView)
this.closeButton = view.findViewById<ImageButton>(R.id.closeButton)
// Action recycler
val spanCount = 3
@ -39,15 +44,14 @@ class KeyboardActionView(context: Context) : AbstractKeyboardView(context),
val spacing = 2.px
val includeEdge = false
this.recyclerView.apply {
recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = dataAdapter
addItemDecoration(GridSpacingItemDecoration(spanCount, spacing, includeEdge))
}
this.closeButton.setOnClickListener {
closeButton.setOnClickListener {
this.keyboardListener?.closeKeyboard()
}
@ -61,7 +65,7 @@ class KeyboardActionView(context: Context) : AbstractKeyboardView(context),
this.positionAdapter = PositionAdapter(it)
} ?: throw PAIllegalStateException("keyboard listener not set")
this.recycler.apply {
recyclerView.apply {
setHasFixedSize(true)
layoutManager = positionViewManager
adapter = positionAdapter
@ -74,7 +78,7 @@ class KeyboardActionView(context: Context) : AbstractKeyboardView(context),
this.positionAdapter.positions = positions
}
override fun adapterRows(): List<RowRepresentable>? {
override fun adapterRows(): List<RowRepresentable> {
return Action.Type.defaultTypes
}
@ -99,7 +103,7 @@ class KeyboardActionView(context: Context) : AbstractKeyboardView(context),
this.dataAdapter.notifyDataSetChanged()
}
override fun textColor(position: Int, row: RowRepresentable): Int? {
override fun textColor(position: Int, row: RowRepresentable): Int {
return if (isEnabled(row, 0)) {
R.color.white
} else {

@ -4,9 +4,11 @@ import android.content.Context
import android.view.LayoutInflater
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputConnection
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import androidx.recyclerview.widget.GridLayoutManager
import kotlinx.android.synthetic.main.view_hand_keyboard_amount.view.*
import androidx.recyclerview.widget.RecyclerView
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
@ -17,7 +19,6 @@ import net.pokeranalytics.android.ui.view.GridSpacingItemDecoration
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.util.extensions.noGroupingFormatted
import timber.log.Timber
import java.text.DecimalFormatSymbols
class NumericKey : RowRepresentable {
@ -77,9 +78,22 @@ class KeyboardAmountView(context: Context) : AbstractKeyboardView(context),
*/
private var inputConnection: InputConnection? = null
private var recyclerView: RecyclerView
private var nextButton: Button
private var kiloButton: Button
private var millionButton: Button
private var clearButton: Button
private var closeButton: ImageView
init {
LayoutInflater.from(context)
val view = LayoutInflater.from(context)
.inflate(R.layout.view_hand_keyboard_amount, this, true)
this.recyclerView = view.findViewById(R.id.recyclerView)
this.nextButton = view.findViewById(R.id.nextButton)
this.kiloButton = view.findViewById(R.id.kiloButton)
this.millionButton = view.findViewById(R.id.millionButton)
this.clearButton = view.findViewById(R.id.clearButton)
this.closeButton = view.findViewById(R.id.closeButton)
val viewManager = GridLayoutManager(context, 3)
this.dataAdapter = RowRepresentableAdapter(this, this)
@ -142,7 +156,7 @@ class KeyboardAmountView(context: Context) : AbstractKeyboardView(context),
}
override fun adapterRows(): List<RowRepresentable>? {
override fun adapterRows(): List<RowRepresentable> {
val keys = mutableListOf<NumericKey>()
(0 until 12).forEach { index ->
val key = when (index) {

@ -2,8 +2,10 @@ package net.pokeranalytics.android.ui.modules.handhistory.views
import android.content.Context
import android.view.LayoutInflater
import android.widget.Button
import android.widget.ImageButton
import androidx.recyclerview.widget.GridLayoutManager
import kotlinx.android.synthetic.main.view_hand_keyboard_card.view.*
import androidx.recyclerview.widget.RecyclerView
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.realm.handhistory.Card
@ -20,10 +22,24 @@ class KeyboardCardView(context: Context) : AbstractKeyboardView(context) {
private lateinit var cardValueAdapter: CardValueAdapter
private lateinit var cardSuitAdapter: CardSuitAdapter
private var valueRecyclerView: RecyclerView
private var suitRecyclerView: RecyclerView
private var nextButton: Button
private var backSpaceButton: Button
private var clearButton: Button
private var closeButton: ImageButton
init {
LayoutInflater.from(context)
val view = LayoutInflater.from(context)
.inflate(R.layout.view_hand_keyboard_card, this, true)
this.valueRecyclerView = view.findViewById(R.id.valueRecyclerView)
this.suitRecyclerView = view.findViewById(R.id.suitRecyclerView)
this.backSpaceButton = view.findViewById(R.id.backSpaceButton)
this.nextButton = view.findViewById(R.id.nextButton)
this.clearButton = view.findViewById(R.id.clearButton)
this.closeButton = view.findViewById(R.id.closeButton)
this.nextButton.setOnClickListener {
this.keyboardListener?.cardSelectionEnded()

@ -1,8 +1,10 @@
package net.pokeranalytics.android.ui.modules.handhistory.views
import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.row_hand_history_view.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
@ -23,13 +25,15 @@ class RowHandHistoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemVie
val handHistory = row as HandHistory
itemView.cardsLayout.removeAllViews()
val cardsLayout = itemView.findViewById<LinearLayout>(R.id.cardsLayout)
cardsLayout.removeAllViews()
handHistory.cardViews(itemView.context, itemView.cardsLayout).forEach { view ->
itemView.cardsLayout.addView(view)
handHistory.cardViews(itemView.context, cardsLayout).forEach { view ->
cardsLayout.addView(view)
}
itemView.amount.text = handHistory.potSizeForStreet(Street.SUMMARY).formatted
val amount = itemView.findViewById<TextView>(R.id.amount)
amount.text = handHistory.potSizeForStreet(Street.SUMMARY).formatted
val heroWins = handHistory.heroWins
val colorId = when(heroWins) {
@ -38,12 +42,14 @@ class RowHandHistoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemVie
else -> R.color.kaki_light
}
itemView.amount.setTextColor(itemView.context.getColor(colorId))
amount.setTextColor(itemView.context.getColor(colorId))
val listener = View.OnClickListener {
delegate?.onRowSelected(position, row)
}
itemView.constraintLayout.setOnClickListener(listener)
val constraintLayout = itemView.findViewById<ConstraintLayout>(R.id.constraintLayout)
constraintLayout.setOnClickListener(listener)
}
}

@ -11,13 +11,13 @@ import androidx.appcompat.content.res.AppCompatResources
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DiffUtil
import kotlinx.android.synthetic.main.fragment_session.*
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager
import net.pokeranalytics.android.calculus.optimalduration.CashGameOptimalDurationCalculator
import net.pokeranalytics.android.databinding.FragmentSessionBinding
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.extensions.SessionState
@ -69,6 +69,9 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
}
}
private var _binding: FragmentSessionBinding? = null
private val binding get() = _binding!!
// private val coroutineContext: CoroutineContext
// get() = Dispatchers.Main
@ -93,9 +96,10 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
}
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)
return inflater.inflate(R.layout.fragment_session, container, false)
_binding = FragmentSessionBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -104,28 +108,33 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
initUI()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
/**
* Init UI
*/
private fun initUI() {
toolbar.title = if (currentSession.isTournament()) getString(R.string.tournament) else getString(R.string.cash_game)
collapsingToolbar.title = toolbar.title
binding.toolbar.title = if (currentSession.isTournament()) getString(R.string.tournament) else getString(R.string.cash_game)
binding.collapsingToolbar.title = binding.toolbar.title
sessionAdapter = RowRepresentableAdapter(this, this)
recyclerView.adapter = sessionAdapter
binding.recyclerView.adapter = sessionAdapter
updateSessionUI(true)
setDisplayHomeAsUpEnabled(true)
val viewManager = SmoothScrollLinearLayoutManager(requireContext())
recyclerView.apply {
binding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
}
floatingActionButton.setOnClickListener {
binding.floatingActionButton.setOnClickListener {
if (this.currentSession.isValidForSave()) {
sessionHasBeenUserCustomized = true
manageSessionState()
@ -279,6 +288,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
val animationDuration = if (firstDisplay) 0L else 300L
val floatingActionButton = binding.floatingActionButton
when (currentSession.getState()) {
SessionState.PENDING, SessionState.PLANNED -> {
sessionMenu?.findItem(R.id.restart)?.isVisible = false
@ -345,17 +355,18 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
* Update adapter UI
*/
private fun updateAdapterUI() {
this.adapterRows()?.let {
val diffResult = DiffUtil.calculateDiff(RowRepresentableDiffCallback(it, oldRows))
sessionAdapter.updateRows(diffResult)
oldRows.clear()
oldRows.addAll(it)
val rows = this.adapterRows()
val diffResult = DiffUtil.calculateDiff(RowRepresentableDiffCallback(rows, oldRows))
this.sessionAdapter.updateRows(diffResult)
this.oldRows.clear()
this.oldRows.addAll(rows)
// if (scrollToTop) {
// recyclerView.smoothScrollToPosition(0)
// }
}
}
/**
@ -373,7 +384,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
}
currentSession.startOrContinue()
this.recyclerView.smoothScrollToPosition(0)
binding.recyclerView.smoothScrollToPosition(0)
}
SessionState.STARTED -> {
@ -493,7 +504,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
// this.rowRepresentationForCurrentState = this.updatedRowRepresentationForCurrentState(requireContext())
}
override fun adapterRows(): List<RowRepresentable>? {
override fun adapterRows(): List<RowRepresentable> {
return this.model.rows
}

@ -4,13 +4,13 @@ import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.layout_legend_default.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.ui.extensions.setTextFormat
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.graph.Graph
import net.pokeranalytics.android.util.TextFormat
interface LegendContent
@ -35,7 +35,7 @@ open class LegendView : FrameLayout {
// rightFormat: TextFormat? = null
// ) : Values("", leftFormat, rightFormat)
private lateinit var legendLayout: ConstraintLayout
protected lateinit var legendLayout: ConstraintLayout
/**
* Constructors
@ -56,28 +56,43 @@ open class LegendView : FrameLayout {
return R.layout.layout_legend_default
}
protected lateinit var stat1Name: TextView
protected lateinit var stat2Name: TextView
protected lateinit var counter: TextView
protected lateinit var stat1Value: TextView
protected lateinit var stat2Value: TextView
protected lateinit var title: TextView
/**
* Init
*/
private fun init() {
protected open fun init() {
val layoutInflater = LayoutInflater.from(context)
legendLayout = layoutInflater.inflate(this.getResourceLayout(), this, false) as ConstraintLayout
val layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
addView(legendLayout, layoutParams)
this.stat1Name = legendLayout.findViewById(R.id.stat1Name)
this.stat2Name = legendLayout.findViewById(R.id.stat2Name)
this.counter = legendLayout.findViewById(R.id.counter)
this.stat1Value = legendLayout.findViewById(R.id.stat1Value)
this.stat2Value = legendLayout.findViewById(R.id.stat2Value)
this.title = legendLayout.findViewById(R.id.title)
}
/**
* Set the stat data to the view
*/
open fun prepareWithStat(stat: Stat, counter: Int? = null, style: GraphFragment.Style) {
open fun prepareWithStat(stat: Stat, counter: Int? = null, style: Graph.Style) {
when (style) {
GraphFragment.Style.BAR -> {
Graph.Style.BAR -> {
this.stat1Name.text = stat.localizedTitle(context)
this.stat2Name.text = context.getString(R.string.sessions)
this.counter.isVisible = false
}
GraphFragment.Style.LINE -> {
Graph.Style.LINE -> {
if (stat.graphSignificantIndividualValue) {
this.stat1Name.text = stat.localizedTitle(context)
this.stat2Name.text = stat.cumulativeLabelResId(context)

@ -2,16 +2,12 @@ package net.pokeranalytics.android.ui.view
import android.content.Context
import android.graphics.drawable.GradientDrawable
import kotlinx.android.synthetic.main.layout_legend_color.view.*
import kotlinx.android.synthetic.main.layout_legend_default.view.stat1Name
import kotlinx.android.synthetic.main.layout_legend_default.view.stat1Value
import kotlinx.android.synthetic.main.layout_legend_default.view.stat2Name
import kotlinx.android.synthetic.main.layout_legend_default.view.stat2Value
import android.view.View
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.ui.extensions.setTextFormat
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.graph.Graph
import net.pokeranalytics.android.util.TextFormat
data class MultilineLegendValues(
var firstTitle: String,
@ -22,11 +18,18 @@ data class MultilineLegendValues(
class MultiLineLegendView(context: Context) : LegendView(context = context) {
private lateinit var coloredCircle: View
override fun init() {
super.init()
this.coloredCircle = legendLayout.findViewById(R.id.coloredCircle)
}
override fun getResourceLayout(): Int {
return R.layout.layout_legend_color
}
override fun prepareWithStat(stat: Stat, counter: Int?, style: GraphFragment.Style) {
override fun prepareWithStat(stat: Stat, counter: Int?, style: Graph.Style) {
}
override fun setItemData(content: LegendContent, color: Int?) {

@ -6,12 +6,14 @@ import android.graphics.drawable.GradientDrawable
import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat.getColor
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import kotlinx.android.synthetic.main.view_player_image.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Player
import net.pokeranalytics.android.ui.extensions.px
@ -43,6 +45,12 @@ class PlayerImageView : FrameLayout {
private lateinit var playerImageView: ConstraintLayout
private lateinit var playerImage: ImageView
private lateinit var playerStroke: TextView
private lateinit var playerInitial: TextView
private lateinit var playerImageSelection: View
private var onImageClickListener: OnClickListener? = null
/**
@ -68,6 +76,12 @@ class PlayerImageView : FrameLayout {
this.playerImageView = layoutInflater.inflate(R.layout.view_player_image, this, false) as ConstraintLayout
val layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
addView(playerImageView, layoutParams)
this.playerImage = this.playerImageView.findViewById(R.id.player_image)
this.playerStroke = this.playerImageView.findViewById(R.id.playerStroke)
this.playerInitial = this.playerImageView.findViewById(R.id.playerInitial)
this.playerImageSelection = this.playerImageView.findViewById(R.id.playerImageSelection)
}
/**
@ -79,14 +93,14 @@ class PlayerImageView : FrameLayout {
player.picture?.let { picture ->
val rDrawable = RoundedBitmapDrawableFactory.create(resources, picture)
rDrawable.isCircular = true
playerImageView.player_image.setImageDrawable(rDrawable)
this.playerImage.setImageDrawable(rDrawable)
} ?: run {
playerImageView.playerStroke.background = ResourcesCompat.getDrawable(resources, R.drawable.circle_stroke_kaki, null)
playerImageView.player_image.setImageDrawable(null)
playerImageView.playerInitial.text = player.initials
playerImageView.playerInitial.setTextSize(TypedValue.COMPLEX_UNIT_SP, size.getFontSize())
this.playerStroke.background = ResourcesCompat.getDrawable(resources, R.drawable.circle_stroke_kaki, null)
this.playerImage.setImageDrawable(null)
this.playerInitial.text = player.initials
this.playerInitial.setTextSize(TypedValue.COMPLEX_UNIT_SP, size.getFontSize())
}
@ -99,17 +113,17 @@ class PlayerImageView : FrameLayout {
}
// Stroke & initial
val drawable = this.playerImageView.playerStroke.background as GradientDrawable?
val drawable = this.playerStroke.background as GradientDrawable?
drawable?.setStroke(size.getStrokeSize(), color)
this.playerImageView.playerInitial.setTextColor(color)
this.playerInitial.setTextColor(color)
// Click listener
if (this.onImageClickListener != null) {
this.playerImageView.playerImageSelection.setOnClickListener {
this.playerImageSelection.setOnClickListener {
this.onImageClickListener?.onClick(it)
}
} else {
this.playerImageView.playerImageSelection.background = null
this.playerImageSelection.background = null
}
}
@ -127,12 +141,12 @@ class PlayerImageView : FrameLayout {
val color = getColor(context, res)
val drawable = this.playerImageView.playerStroke.background as GradientDrawable?
val drawable = this.playerStroke.background as GradientDrawable?
drawable?.setStroke(size.getStrokeSize(), color)
this.playerImageView.playerInitial.text = text
this.playerImageView.playerInitial.setTextColor(color)
this.playerImageView.playerInitial.setTextSize(TypedValue.COMPLEX_UNIT_SP, size.getFontSize())
this.playerInitial.text = text
this.playerInitial.setTextColor(color)
this.playerInitial.setTextSize(TypedValue.COMPLEX_UNIT_SP, size.getFontSize())
}
/**
@ -141,17 +155,17 @@ class PlayerImageView : FrameLayout {
fun setOnImageClickListener(onImageClickListener: OnClickListener) {
this.onImageClickListener = onImageClickListener
this.playerImageView.playerImageSelection.setOnClickListener {
this.playerImageSelection.setOnClickListener {
this.onImageClickListener?.onClick(it)
}
}
fun clear(size: Size = Size.NORMAL) {
val drawable = this.playerImageView.playerStroke.background as GradientDrawable?
val drawable = this.playerStroke.background as GradientDrawable?
drawable?.setStroke(size.getStrokeSize(), getColor(context, R.color.kaki))
this.playerImageView.playerInitial.text = null
this.playerInitial.text = null
}
}

@ -15,9 +15,8 @@ import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.data.*
import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup
import kotlinx.android.synthetic.main.row_feed_session.view.*
import kotlinx.android.synthetic.main.row_transaction.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.AxisFormatting
import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager
@ -33,7 +32,6 @@ import net.pokeranalytics.android.ui.extensions.ChipGroupExtension
import net.pokeranalytics.android.ui.extensions.px
import net.pokeranalytics.android.ui.extensions.setTextFormat
import net.pokeranalytics.android.ui.modules.bankroll.BankrollRowRepresentable
import net.pokeranalytics.android.ui.graph.AxisFormatting
import net.pokeranalytics.android.ui.graph.setStyle
import net.pokeranalytics.android.ui.modules.handhistory.views.RowHandHistoryViewHolder
import net.pokeranalytics.android.ui.view.holder.RowViewHolder
@ -435,11 +433,13 @@ enum class RowViewType(private var layoutRes: Int) : ViewIdentifier {
inner class RowSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
itemView.sessionRow.setData(row as Session)
val sessionRow = itemView.findViewById<SessionRowView>(R.id.sessionRow)
sessionRow.setData(row as Session)
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.sessionRow.setOnClickListener(listener)
sessionRow.setOnClickListener(listener)
}
}
@ -449,11 +449,13 @@ enum class RowViewType(private var layoutRes: Int) : ViewIdentifier {
inner class RowTransactionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
itemView.transactionRow.setData(row as Transaction)
val transactionRow = itemView.findViewById<TransactionRowView>(R.id.transactionRow)
transactionRow.setData(row as Transaction)
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.transactionRow.setOnClickListener(listener)
transactionRow.setOnClickListener(listener)
}
}

@ -4,9 +4,10 @@ import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.row_session_view.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.Stat
@ -27,6 +28,19 @@ class SessionRowView : FrameLayout {
private lateinit var rowSession: ConstraintLayout
private lateinit var dateDay: TextView
private lateinit var dateNumber: TextView
private lateinit var sessionTitle: TextView
private lateinit var sessionInfoDurationIcon: ImageView
private lateinit var sessionInfoDurationValue: TextView
private lateinit var sessionInfoLocationIcon: ImageView
private lateinit var sessionInfoLocationValue: TextView
private lateinit var sessionInfoTableIcon: ImageView
private lateinit var sessionInfoTableValue: TextView
private lateinit var gameResult: TextView
private lateinit var infoIcon: ImageView
private lateinit var infoTitle: TextView
/**
* Constructors
*/
@ -48,8 +62,21 @@ class SessionRowView : FrameLayout {
private fun init() {
val layoutInflater = LayoutInflater.from(context)
rowSession = layoutInflater.inflate(R.layout.row_session_view, this, false) as ConstraintLayout
val layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT)
val layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
addView(rowSession, layoutParams)
this.dateDay = rowSession.findViewById(R.id.dateDay)
this.dateNumber = rowSession.findViewById(R.id.dateNumber)
this.sessionTitle = rowSession.findViewById(R.id.sessionTitle)
this.sessionInfoDurationIcon = rowSession.findViewById(R.id.sessionInfoDurationIcon)
this.sessionInfoDurationValue = rowSession.findViewById(R.id.sessionInfoDurationValue)
this.sessionInfoLocationIcon = rowSession.findViewById(R.id.sessionInfoLocationIcon)
this.sessionInfoLocationValue = rowSession.findViewById(R.id.sessionInfoLocationValue)
this.sessionInfoTableIcon = rowSession.findViewById(R.id.sessionInfoTableIcon)
this.sessionInfoTableValue = sessionInfoTableValue.findViewById(R.id.dateDay)
this.gameResult = rowSession.findViewById(R.id.gameResult)
this.infoIcon = rowSession.findViewById(R.id.infoIcon)
this.infoTitle = rowSession.findViewById(R.id.infoTitle)
}
/**
@ -60,69 +87,69 @@ class SessionRowView : FrameLayout {
val date = session.startDate ?: session.creationDate
// Date
rowSession.dateDay.text = date.getShortDayName()
rowSession.dateNumber.text = date.getDayNumber()
this.dateDay.text = date.getShortDayName()
this.dateNumber.text = date.getDayNumber()
// Title / Game type
rowSession.sessionTitle.text = session.getFormattedGameType(context)
this.sessionTitle.text = session.getFormattedGameType(context)
// Duration
rowSession.sessionInfoDurationValue.text = session.getFormattedDuration()
this.sessionInfoDurationValue.text = session.getFormattedDuration()
// Location
rowSession.sessionInfoLocationIcon.isVisible = session.location != null
rowSession.sessionInfoLocationValue.isVisible = session.location != null
this.sessionInfoLocationIcon.isVisible = session.location != null
this.sessionInfoLocationValue.isVisible = session.location != null
session.location?.let {
rowSession.sessionInfoLocationValue.text = it.name
this.sessionInfoLocationValue.text = it.name
}
// Table size
rowSession.sessionInfoTableIcon.isVisible = session.tableSize != null
rowSession.sessionInfoTableValue.isVisible = session.tableSize != null
this.sessionInfoTableIcon.isVisible = session.tableSize != null
this.sessionInfoTableValue.isVisible = session.tableSize != null
session.tableSize?.let {
rowSession.sessionInfoTableValue.text = TableSize(it).localizedTitle(context)
this.sessionInfoTableValue.text = TableSize(it).localizedTitle(context)
}
val state = session.getState()
rowSession.sessionInfoDurationIcon.isVisible = state.hasStarted
rowSession.sessionInfoDurationValue.isVisible = state.hasStarted
this.sessionInfoDurationIcon.isVisible = state.hasStarted
this.sessionInfoDurationValue.isVisible = state.hasStarted
// State
when (state) {
SessionState.STARTED -> {
rowSession.gameResult.isVisible = false
rowSession.infoIcon.isVisible = true
rowSession.infoIcon.setImageResource(R.drawable.ic_play_circle_outline)
rowSession.infoTitle.isVisible = true
rowSession.infoTitle.text = context.getString(R.string.running_session_state)
this.gameResult.isVisible = false
this.infoIcon.isVisible = true
this.infoIcon.setImageResource(R.drawable.ic_play_circle_outline)
this.infoTitle.isVisible = true
this.infoTitle.text = context.getString(R.string.running_session_state)
}
SessionState.PAUSED -> {
rowSession.gameResult.isVisible = false
rowSession.infoIcon.isVisible = true
rowSession.infoIcon.setImageResource(R.drawable.ic_pause_circle_outline)
rowSession.infoTitle.isVisible = true
rowSession.infoTitle.text = context.getString(R.string.paused_session_state)
this.gameResult.isVisible = false
this.infoIcon.isVisible = true
this.infoIcon.setImageResource(R.drawable.ic_pause_circle_outline)
this.infoTitle.isVisible = true
this.infoTitle.text = context.getString(R.string.paused_session_state)
}
SessionState.PLANNED -> {
rowSession.gameResult.isVisible = false
rowSession.infoIcon.isVisible = true
rowSession.infoIcon.setImageResource(R.drawable.ic_planned)
rowSession.infoTitle.isVisible = true
rowSession.infoTitle.text = session.startDate!!.shortTime()
this.gameResult.isVisible = false
this.infoIcon.isVisible = true
this.infoIcon.setImageResource(R.drawable.ic_planned)
this.infoTitle.isVisible = true
this.infoTitle.text = session.startDate!!.shortTime()
}
SessionState.PENDING -> {
rowSession.gameResult.isVisible = false
rowSession.infoIcon.isVisible = false
rowSession.infoTitle.isVisible = false
this.gameResult.isVisible = false
this.infoIcon.isVisible = false
this.infoTitle.isVisible = false
}
else -> {
rowSession.gameResult.isVisible = true
rowSession.infoIcon.isVisible = false
rowSession.infoTitle.isVisible = false
this.gameResult.isVisible = true
this.infoIcon.isVisible = false
this.infoTitle.isVisible = false
session.result?.net?.let { netResult ->
val stat = ComputedStat(Stat.NET_RESULT, netResult, currency = session.currency)
rowSession.gameResult.setTextFormat(stat.textFormat, context)
this.gameResult.setTextFormat(stat.textFormat, context)
}
// val formattedStat = ComputedStat(Stat.NET_RESULT, result, currency = session.currency).format()

@ -4,8 +4,8 @@ import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import kotlinx.android.synthetic.main.row_transaction_view.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.Stat
@ -52,21 +52,21 @@ class TransactionRowView : FrameLayout {
fun setData(transaction: Transaction) {
// Date
rowTransaction.transactionDateDay.text = transaction.date.getShortDayName()
rowTransaction.transactionDateNumber.text = transaction.date.getDayNumber()
rowTransaction.findViewById<TextView>(R.id.transactionDateDay).text = transaction.date.getShortDayName()
rowTransaction.findViewById<TextView>(R.id.transactionDateNumber).text = transaction.date.getDayNumber()
// Title / Game type
val title = transaction.type?.name ?: "" + " " + transaction.comment
val subtitle = transaction.bankroll?.name
rowTransaction.transactionTitle.text = title
rowTransaction.transactionSubtitle.text = subtitle
rowTransaction.findViewById<TextView>(R.id.transactionTitle).text = title
rowTransaction.findViewById<TextView>(R.id.transactionSubtitle).text = subtitle
// Amount
val computedStat = ComputedStat(Stat.NET_RESULT,
transaction.amount,
currency = transaction.bankroll?.utilCurrency)
rowTransaction.transactionAmount.setTextFormat(computedStat.textFormat, context)
rowTransaction.findViewById<TextView>(R.id.transactionAmount).setTextFormat(computedStat.textFormat, context)
}

@ -4,10 +4,10 @@ import android.content.Context
import androidx.lifecycle.ViewModel
import com.github.mikephil.charting.data.BarDataSet
import com.github.mikephil.charting.data.LineDataSet
import net.pokeranalytics.android.calculus.AxisFormatting
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.graph.AxisFormatting
import net.pokeranalytics.android.ui.graph.Graph
open class GraphViewModel : ViewModel(), GraphDataProvider {
@ -19,7 +19,7 @@ open class GraphViewModel : ViewModel(), GraphDataProvider {
/***
* The graph style
*/
var style: GraphFragment.Style? = null
var style: Graph.Style? = null
/***
* The displayed stat

@ -3,10 +3,9 @@ package net.pokeranalytics.android.ui.viewmodel
import android.content.Context
import com.github.mikephil.charting.data.BarDataSet
import com.github.mikephil.charting.data.LineDataSet
import net.pokeranalytics.android.calculus.AxisFormatting
import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.graph.AxisFormatting
interface ReportHolder {

@ -3,6 +3,9 @@ package net.pokeranalytics.android.ui.viewmodel
import android.content.Context
import com.github.mikephil.charting.data.BarDataSet
import com.github.mikephil.charting.data.LineDataSet
import net.pokeranalytics.android.calcul.barEntries
import net.pokeranalytics.android.calcul.lineEntries
import net.pokeranalytics.android.calcul.multiLineEntries
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.ui.activity.components.ReportParameters
@ -15,7 +18,7 @@ class ReportViewModel : GraphViewModel(), ReportHolder, GraphDataProvider {
companion object {
// Unparcel fails when setting a custom Parcelable object on Entry so we use a static reference to passe objects
// Unparcel fails when setting a custom Parcelable object on Entry so we use a static reference to pass objects
private var _parameters: ReportParameters? = null
val parameters: ReportParameters?

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"

@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.4.10'
ext.kotlin_version = '1.4.21'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.2'
classpath 'com.android.tools.build:gradle:4.1.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'io.realm:realm-gradle-plugin:5.15.2'

@ -35,4 +35,6 @@ android.enableBuildCache=true
# Enable simple gradle caching
org.gradle.caching=true
kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.native.enableDependencyPropagation=false

@ -1,6 +1,6 @@
#Mon Oct 05 18:40:01 CEST 2020
#Wed Dec 09 14:45:29 CET 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

@ -1 +1,2 @@
include ':shared'
include ':app'

@ -0,0 +1,42 @@
plugins {
kotlin("multiplatform")
id("com.android.library")
}
kotlin {
android()
ios {
binaries {
framework {
baseName = "shared"
}
}
}
sourceSets {
val commonMain by getting
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val androidMain by getting
val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation("junit:junit:4.13")
}
}
val iosMain by getting
val iosTest by getting
}
}
android {
compileSdkVersion(29)
defaultConfig {
minSdkVersion(24)
targetSdkVersion(29)
}
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
}

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="net.pokeranalytics.shared" />

@ -0,0 +1,5 @@
package net.pokeranalytics.shared
actual class Platform actual constructor() {
actual val platform: String = "Android ${android.os.Build.VERSION.SDK_INT}"
}

@ -0,0 +1,12 @@
package net.pokeranalytics.shared
import org.junit.Assert.assertTrue
import org.junit.Test
class GreetingTest {
@Test
fun testExample() {
assertTrue("Check Android is mentioned", Greeting().greeting().contains("Android"))
}
}

@ -0,0 +1,7 @@
package net.pokeranalytics.shared
class Greeting {
fun greeting(): String {
return "Hello, ${Platform().platform}!"
}
}

@ -0,0 +1,5 @@
package net.pokeranalytics.shared
expect class Platform() {
val platform: String
}

@ -0,0 +1,8 @@
package net.pokeranalytics.shared
import platform.UIKit.UIDevice
actual class Platform actual constructor() {
actual val platform: String =
UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}

@ -0,0 +1,12 @@
package net.pokeranalytics.shared
import kotlin.test.Test
import kotlin.test.assertTrue
class GreetingTest {
@Test
fun testExample() {
assertTrue(Greeting().greeting().contains("iOS"), "Check iOS is mentioned")
}
}
Loading…
Cancel
Save