Laurent 7 years ago
commit 5ee584f67b
  1. 19
      app/src/main/java/net/pokeranalytics/android/model/LiveData.kt
  2. 7
      app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt
  3. 4
      app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt
  4. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt
  5. 3
      app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt
  6. 166
      app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt
  7. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt
  8. 4
      app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt
  9. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/ReportSetup.kt
  10. 4
      app/src/main/java/net/pokeranalytics/android/model/realm/TournamentFeature.kt
  11. 4
      app/src/main/java/net/pokeranalytics/android/model/realm/TournamentName.kt
  12. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt
  13. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt
  14. 29
      app/src/main/java/net/pokeranalytics/android/ui/activity/DataListActivity.kt
  15. 8
      app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt
  16. 6
      app/src/main/java/net/pokeranalytics/android/ui/extensions/UIExtensions.kt
  17. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt
  18. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ComparisonChartFragment.kt
  19. 58
      app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt
  20. 1
      app/src/main/java/net/pokeranalytics/android/ui/fragment/FilterDetailsFragment.kt
  21. 24
      app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt
  22. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportCreationFragment.kt
  23. 8
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt
  24. 10
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/FilterableFragment.kt
  25. 18
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt
  26. 9
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetEditTextFragment.kt
  27. 5
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt
  28. 7
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListFragment.kt
  29. 5
      app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt
  30. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt
  31. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/data/EditableDataFragment.kt
  32. 48
      app/src/main/java/net/pokeranalytics/android/ui/interfaces/FilterHandler.kt
  33. 10
      app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt
  34. 9
      app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt
  35. 2
      app/src/main/res/layout/fragment_feed.xml
  36. 121
      app/src/main/res/layout/row_title_value_action.xml
  37. 6
      app/src/main/res/values/strings.xml

@ -19,9 +19,9 @@ enum class LiveData : Localizable {
TOURNAMENT_FEATURE, TOURNAMENT_FEATURE,
TRANSACTION, TRANSACTION,
TRANSACTION_TYPE, TRANSACTION_TYPE,
FILTER, FILTER,
CUSTOM_FIELD, CUSTOM_FIELD,
REPORT_SETUP; REPORT_SETUP;
val relatedEntity: Class<out Identifiable> val relatedEntity: Class<out Identifiable>
get() { get() {
@ -33,7 +33,7 @@ enum class LiveData : Localizable {
TOURNAMENT_FEATURE -> TournamentFeature::class.java TOURNAMENT_FEATURE -> TournamentFeature::class.java
TRANSACTION -> Transaction::class.java TRANSACTION -> Transaction::class.java
TRANSACTION_TYPE -> TransactionType::class.java TRANSACTION_TYPE -> TransactionType::class.java
FILTER -> Filter::class.java FILTER -> Filter::class.java
CUSTOM_FIELD -> CustomField::class.java CUSTOM_FIELD -> CustomField::class.java
REPORT_SETUP -> ReportSetup::class.java REPORT_SETUP -> ReportSetup::class.java
} }
@ -48,7 +48,7 @@ enum class LiveData : Localizable {
} }
} }
private fun newEntity(): RealmModel{ private fun newEntity(): RealmModel {
return this.relatedEntity.newInstance() return this.relatedEntity.newInstance()
} }
@ -73,7 +73,7 @@ enum class LiveData : Localizable {
TOURNAMENT_FEATURE -> R.string.tournament_feature TOURNAMENT_FEATURE -> R.string.tournament_feature
TRANSACTION -> R.string.operations TRANSACTION -> R.string.operations
TRANSACTION_TYPE -> R.string.operation_types TRANSACTION_TYPE -> R.string.operation_types
FILTER -> R.string.filter FILTER -> R.string.filter
CUSTOM_FIELD -> R.string.custom_fields CUSTOM_FIELD -> R.string.custom_fields
REPORT_SETUP -> R.string.custom REPORT_SETUP -> R.string.custom
} }
@ -86,4 +86,11 @@ enum class LiveData : Localizable {
return "${context.getString(R.string.new_str)} ${this.localizedTitle(context).toLowerCase()}" return "${context.getString(R.string.new_str)} ${this.localizedTitle(context).toLowerCase()}"
} }
/**
* Return the update entity titleResId
*/
fun updateEntityLocalizedTitle(context: Context): String {
return "${context.getString(R.string.update_entity)} ${this.localizedTitle(context).toLowerCase()}"
}
} }

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.interfaces package net.pokeranalytics.android.model.interfaces
import android.content.Context
import io.realm.Realm import io.realm.Realm
import io.realm.RealmModel import io.realm.RealmModel
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
@ -106,11 +107,11 @@ interface Deletable : Identifiable {
/** /**
* A method to define if an object is safe for deletion in database * A method to define if an object is safe for deletion in database
*/ */
fun isValidForDelete(realm: Realm): Boolean fun isValidForDelete(context: Context, realm: Realm): Boolean
fun getDeleteStatus(realm: Realm): DeleteValidityStatus { fun getDeleteStatus(context: Context, realm: Realm): DeleteValidityStatus {
if (!isValidForDelete(realm)) { if (!isValidForDelete(context, realm)) {
return DeleteValidityStatus.INVALID return DeleteValidityStatus.INVALID
} }
return DeleteValidityStatus.VALID return DeleteValidityStatus.VALID

@ -66,12 +66,12 @@ open class Bankroll : RealmObject(), NameManageable, RowRepresentable {
} }
} }
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(context: Context, realm: Realm): Boolean {
return realm.where<Session>().equalTo("bankroll.id", id).findAll().isEmpty() return realm.where<Session>().equalTo("bankroll.id", id).findAll().isEmpty()
&& realm.where<Transaction>().equalTo("bankroll.id", id).findAll().isEmpty() && realm.where<Transaction>().equalTo("bankroll.id", id).findAll().isEmpty()
} }
override fun getDeleteStatus(realm: Realm): DeleteValidityStatus { override fun getDeleteStatus(context: Context, realm: Realm): DeleteValidityStatus {
return if (!realm.where<Session>().equalTo("bankroll.id", id).findAll().isEmpty()) { return if (!realm.where<Session>().equalTo("bankroll.id", id).findAll().isEmpty()) {
DeleteValidityStatus.SESSIONS_LINKED DeleteValidityStatus.SESSIONS_LINKED
} else if (!realm.where<Transaction>().equalTo("bankroll.id", id).findAll().isEmpty()) { } else if (!realm.where<Transaction>().equalTo("bankroll.id", id).findAll().isEmpty()) {

@ -117,7 +117,7 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa
return realm.where(this::class.java).equalTo("name", this.name).and().notEqualTo("id", this.id).findAll().isNotEmpty() return realm.where(this::class.java).equalTo("name", this.name).and().notEqualTo("id", this.id).findAll().isNotEmpty()
} }
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(context: Context, realm: Realm): Boolean {
return true return true
} }

@ -10,7 +10,6 @@ import io.realm.kotlin.where
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.ModelException import net.pokeranalytics.android.exceptions.ModelException
import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus
import net.pokeranalytics.android.model.interfaces.Manageable
import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType
@ -95,7 +94,7 @@ open class CustomFieldEntry : RealmObject(), NameManageable, RowRepresentable {
this.value = value as String? ?: "" this.value = value as String? ?: ""
} }
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(context: Context, realm: Realm): Boolean {
if (realm.where<Session>().contains("customFieldEntries.id", id).findAll().isNotEmpty()) { if (realm.where<Session>().contains("customFieldEntries.id", id).findAll().isNotEmpty()) {
return false return false
} }

@ -12,8 +12,11 @@ import net.pokeranalytics.android.model.interfaces.Deletable
import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus
import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.ui.interfaces.FilterableType import net.pokeranalytics.android.ui.interfaces.FilterableType
import net.pokeranalytics.android.ui.view.ImageDecorator
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
import net.pokeranalytics.android.util.Preferences
import java.util.* import java.util.*
/** /**
@ -21,14 +24,14 @@ import java.util.*
* It contains a list of [FilterCondition] describing the complete query to launch * It contains a list of [FilterCondition] describing the complete query to launch
* The [Filter] is working closely with a [Filterable] interface providing the entity we want the query being launched on * The [Filter] is working closely with a [Filterable] interface providing the entity we want the query being launched on
*/ */
open class Filter : RealmObject(), RowRepresentable, Identifiable, Deletable { open class Filter : RealmObject(), RowRepresentable, Identifiable, Deletable, ImageDecorator {
companion object { companion object {
// Create a new instance // Create a new instance
fun newInstance(realm: Realm, filterableType:Int): Filter { fun newInstance(realm: Realm, filterableType: Int): Filter {
val filter = Filter() val filter = Filter()
filter.filterableTypeOrdinal = filterableType filter.filterableTypeOrdinal = filterableType
return filter return filter
//return realm.copyToRealm(filter) //return realm.copyToRealm(filter)
} }
@ -38,26 +41,26 @@ open class Filter : RealmObject(), RowRepresentable, Identifiable, Deletable {
return realm.where<Filter>().equalTo("id", filterId).findFirst() return realm.where<Filter>().equalTo("id", filterId).findFirst()
} }
inline fun <reified T : Filterable> queryOn(realm: Realm, query: Query, sortField: String? = null): RealmResults<T> { inline fun <reified T : Filterable> queryOn(realm: Realm, query: Query, sortField: String? = null): RealmResults<T> {
val realmQuery = realm.where<T>() val realmQuery = realm.where<T>()
sortField?.let { sortField?.let {
return query.queryWith(realmQuery).sort(it).findAll() return query.queryWith(realmQuery).sort(it).findAll()
} ?: run { } ?: run {
return query.queryWith(realmQuery).findAll() return query.queryWith(realmQuery).findAll()
} }
} }
fun sortedByUsage(realm: Realm): RealmResults<Filter> { fun sortedByUsage(realm: Realm): RealmResults<Filter> {
return realm.where(Filter::class.java).findAll().sort("usageCount") return realm.where(Filter::class.java).findAll().sort("usageCount")
} }
} }
@PrimaryKey @PrimaryKey
override var id = UUID.randomUUID().toString() override var id = UUID.randomUUID().toString()
// the queryWith name // the queryWith name
var name: String = "" var name: String = ""
// the number of use of the queryWith, // the number of use of the queryWith,
// for MutableRealmInteger, see https://realm.io/docs/java/latest/#counters // for MutableRealmInteger, see https://realm.io/docs/java/latest/#counters
@ -66,112 +69,121 @@ open class Filter : RealmObject(), RowRepresentable, Identifiable, Deletable {
var filterConditions: RealmList<FilterCondition> = RealmList() var filterConditions: RealmList<FilterCondition> = RealmList()
private set private set
private var filterableTypeOrdinal: Int? = null private var filterableTypeOrdinal: Int? = null
val filterableType: FilterableType override val viewType: Int
get() { get() = RowViewType.TITLE_VALUE_ACTION.ordinal
this.filterableTypeOrdinal?.let { override val imageRes: Int?
return FilterableType.values()[it] get() = R.drawable.ic_outline_settings
} override val imageTint: Int?
return FilterableType.ALL get() = R.color.green
} override val imageClickable: Boolean?
get() = true
val filterableType: FilterableType
get() {
this.filterableTypeOrdinal?.let {
return FilterableType.values()[it]
}
return FilterableType.ALL
}
fun createOrUpdateFilterConditions(filterConditionRows: ArrayList<QueryCondition>) { fun createOrUpdateFilterConditions(filterConditionRows: ArrayList<QueryCondition>) {
println("list of querys saving: ${filterConditionRows.map { it.id }}") println("list of querys saving: ${filterConditionRows.map { it.id }}")
println("list of querys previous: ${this.filterConditions.map { it.queryCondition.id }}") println("list of querys previous: ${this.filterConditions.map { it.queryCondition.id }}")
filterConditionRows filterConditionRows
.map { .map {
it.groupId it.groupId
} }
.distinct() .distinct()
.forEach { groupId-> .forEach { groupId ->
filterConditionRows filterConditionRows
.filter { .filter {
it.groupId == groupId it.groupId == groupId
} }
.apply { .apply {
println("list of querys: ${this.map { it.id }}") println("list of querys: ${this.map { it.id }}")
val casted = arrayListOf<QueryCondition>() val casted = arrayListOf<QueryCondition>()
casted.addAll(this) casted.addAll(this)
val newFilterCondition = FilterCondition(casted) val newFilterCondition = FilterCondition(casted)
val previousCondition = filterConditions.filter { val previousCondition = filterConditions.filter {
it.filterName == newFilterCondition.filterName && it.operator == newFilterCondition.operator it.filterName == newFilterCondition.filterName && it.operator == newFilterCondition.operator
} }
filterConditions.removeAll(previousCondition) filterConditions.removeAll(previousCondition)
filterConditions.add(newFilterCondition) filterConditions.add(newFilterCondition)
} }
} }
} }
fun remove(filterCategoryRow: FilterCategoryRow) { fun remove(filterCategoryRow: FilterCategoryRow) {
val sections = filterCategoryRow.filterSectionRows.map { it.name } val sections = filterCategoryRow.filterSectionRows.map { it.name }
val savedSections = filterConditions.filter { sections.contains(it.sectionName) } val savedSections = filterConditions.filter { sections.contains(it.sectionName) }
this.filterConditions.removeAll(savedSections) this.filterConditions.removeAll(savedSections)
} }
fun countBy(filterCategoryRow: FilterCategoryRow): Int { fun countBy(filterCategoryRow: FilterCategoryRow): Int {
val sections = filterCategoryRow.filterSectionRows.map { it.name } val sections = filterCategoryRow.filterSectionRows.map { it.name }
println("list of sections $sections") println("list of sections $sections")
val savedSections = filterConditions.filter { sections.contains(it.sectionName) }.flatMap { it.queryCondition.id } val savedSections = filterConditions.filter { sections.contains(it.sectionName) }.flatMap { it.queryCondition.id }
println("list of savedSections $savedSections") println("list of savedSections $savedSections")
return savedSections.size return savedSections.size
} }
fun contains(filterElementRow: QueryCondition): Boolean { fun contains(filterElementRow: QueryCondition): Boolean {
println("list of saved queries ${filterConditions.map { it.queryCondition.id }}") println("list of saved queries ${filterConditions.map { it.queryCondition.id }}")
println("list of contains ${filterElementRow.id}") println("list of contains ${filterElementRow.id}")
val contained = filterConditions.flatMap{ it.queryCondition.id }.contains(filterElementRow.id.first()) val contained = filterConditions.flatMap { it.queryCondition.id }.contains(filterElementRow.id.first())
println("list of : $contained") println("list of : $contained")
return contained return contained
} }
/** /**
* Get the saved value for the given [filterElementRow] * Get the saved value for the given [filterElementRow]
*/ */
fun loadValueForElement(filterElementRow: QueryCondition) { fun loadValueForElement(filterElementRow: QueryCondition) {
val filtered = filterConditions.filter { val filtered = filterConditions.filter {
it.queryCondition.id == filterElementRow.id it.queryCondition.id == filterElementRow.id
} }
if (filtered.isNotEmpty()) { if (filtered.isNotEmpty()) {
return filterElementRow.updateValueBy(filtered.first()) return filterElementRow.updateValueBy(filtered.first())
} }
} }
inline fun <reified T : Filterable> results(firstField: String? = null, secondField: String? = null): RealmResults<T> { inline fun <reified T : Filterable> results(firstField: String? = null, secondField: String? = null): RealmResults<T> {
val realmQuery = realm.where<T>() val realmQuery = realm.where<T>()
if (firstField != null && secondField != null) { if (firstField != null && secondField != null) {
return this.query.queryWith(realmQuery).distinct(firstField, secondField).findAll() return this.query.queryWith(realmQuery).distinct(firstField, secondField).findAll()
} }
if (firstField != null) { if (firstField != null) {
return this.query.queryWith(realmQuery).distinct(firstField).findAll() return this.query.queryWith(realmQuery).distinct(firstField).findAll()
} }
return this.query.queryWith(realmQuery).findAll() return this.query.queryWith(realmQuery).findAll()
} }
val query: Query val query: Query
get() { get() {
val query = Query() val query = Query()
this.filterConditions.forEach { this.filterConditions.forEach {
query.add(it.queryCondition) query.add(it.queryCondition)
} }
return query return query
} }
override fun getDisplayName(context: Context): String { override fun getDisplayName(context: Context): String {
if (name.isNotEmpty()) return name if (name.isNotEmpty()) return name
return this.query.getName(context) return this.query.getName(context)
} }
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(context: Context, realm: Realm): Boolean {
return true return id != Preferences.getActiveFilterId(context)
} }
override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int { override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int {
return R.string.relationship_error return R.string.filter_currently_selected
} }
} }

@ -91,7 +91,7 @@ open class Game : RealmObject(), NameManageable, StaticRowRepresentableDataSourc
} }
} }
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(context: Context, realm: Realm): Boolean {
return realm.where<Session>().equalTo("game.id", id).findAll().isEmpty() return realm.where<Session>().equalTo("game.id", id).findAll().isEmpty()
} }
} }

@ -7,8 +7,8 @@ import io.realm.RealmObject
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow
import java.util.* import java.util.*
@ -59,7 +59,7 @@ open class Location : RealmObject(), NameManageable, RowRepresentable {
} }
} }
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(context: Context, realm: Realm): Boolean {
return realm.where<Session>().equalTo("location.id", id).findAll().isEmpty() return realm.where<Session>().equalTo("location.id", id).findAll().isEmpty()
} }
} }

@ -70,7 +70,7 @@ open class ReportSetup : RealmObject(), RowRepresentable, Deletable {
// Deletable // Deletable
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(context: Context, realm: Realm): Boolean {
return true return true
} }

@ -7,8 +7,8 @@ import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.interfaces.CountableUsage import net.pokeranalytics.android.model.interfaces.CountableUsage
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
@ -73,7 +73,7 @@ open class TournamentFeature : RealmObject(), NameManageable, StaticRowRepresent
} }
} }
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(context: Context, realm: Realm): Boolean {
return realm.where<Session>().equalTo("tournamentFeatures.id", id).findAll().isEmpty() return realm.where<Session>().equalTo("tournamentFeatures.id", id).findAll().isEmpty()
} }
} }

@ -6,8 +6,8 @@ import io.realm.RealmObject
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
@ -67,7 +67,7 @@ open class TournamentName : RealmObject(), NameManageable, StaticRowRepresentabl
} }
} }
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(context: Context, realm: Realm): Boolean {
return realm.where<Session>().equalTo("tournamentName.id", id).findAll().isEmpty() return realm.where<Session>().equalTo("tournamentName.id", id).findAll().isEmpty()
} }
} }

@ -115,7 +115,7 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo
return realm.where<Transaction>().equalTo("id", id).findFirst() != null return realm.where<Transaction>().equalTo("id", id).findFirst() != null
} }
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(context: Context, realm: Realm): Boolean {
return true return true
} }

@ -90,7 +90,7 @@ open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentab
} }
} }
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(context: Context, realm: Realm): Boolean {
return true return true
} }

@ -14,8 +14,9 @@ class DataListActivity : PokerAnalyticsActivity() {
enum class IntentKey(val keyName: String) { enum class IntentKey(val keyName: String) {
DATA_TYPE("DATA_TYPE"), DATA_TYPE("DATA_TYPE"),
LIVE_DATA_TYPE("LIVE_DATA_TYPE"), LIVE_DATA_TYPE("LIVE_DATA_TYPE"),
ITEM_DELETED("ITEM_DELETED") ITEM_DELETED("ITEM_DELETED"),
SHOW_ADD_BUTTON("SHOW_ADD_BUTTON"),
} }
companion object { companion object {
@ -23,17 +24,18 @@ class DataListActivity : PokerAnalyticsActivity() {
context.startActivity(getIntent(context, dataType)) context.startActivity(getIntent(context, dataType))
} }
fun newSelectInstance(fragment: Fragment, dataType: Int) { fun newSelectInstance(fragment: Fragment, dataType: Int, showAddButton: Boolean = true) {
val context = fragment.requireContext() val context = fragment.requireContext()
fragment.startActivityForResult(getIntent(context, dataType), FilterActivityRequestCode.SELECT_FILTER.ordinal) fragment.startActivityForResult(getIntent(context, dataType, showAddButton), FilterActivityRequestCode.SELECT_FILTER.ordinal)
} }
private fun getIntent(context:Context, dataType:Int) : Intent { private fun getIntent(context: Context, dataType: Int, showAddButton: Boolean = true): Intent {
val intent = Intent(context, DataListActivity::class.java) val intent = Intent(context, DataListActivity::class.java)
intent.putExtra(IntentKey.DATA_TYPE.keyName, dataType) intent.putExtra(IntentKey.DATA_TYPE.keyName, dataType)
return intent intent.putExtra(IntentKey.SHOW_ADD_BUTTON.keyName, showAddButton)
} return intent
} }
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -46,10 +48,11 @@ class DataListActivity : PokerAnalyticsActivity() {
* Init UI * Init UI
*/ */
private fun initUI() { private fun initUI() {
val dataType = intent.getIntExtra(IntentKey.DATA_TYPE.keyName, 0) val dataType = intent.getIntExtra(IntentKey.DATA_TYPE.keyName, 0)
val showAddButton = intent.getBooleanExtra(IntentKey.SHOW_ADD_BUTTON.keyName, true)
val fragment = dataListFragment as DataListFragment val fragment = dataListFragment as DataListFragment
fragment.setData(dataType) fragment.setData(dataType)
fragment.updateUI(showAddButton)
} }
} }

@ -30,8 +30,6 @@ interface RowRepresentableDataSource: EditableDataSource, DisplayableDataSource,
*/ */
fun viewTypeForPosition(position:Int): Int fun viewTypeForPosition(position:Int): Int
//TODO should be removed
fun indexForRow(row: RowRepresentable): Int
} }
/** /**
@ -61,12 +59,6 @@ interface StaticRowRepresentableDataSource: RowRepresentableDataSource {
throw IllegalStateException("Need to implement Data Source") throw IllegalStateException("Need to implement Data Source")
} }
override fun indexForRow(row: RowRepresentable): Int {
this.adapterRows()?.let {
return it.indexOf(row)
}
throw IllegalStateException("Need to implement Data Source")
}
} }

@ -5,6 +5,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.Resources import android.content.res.Resources
import android.net.Uri import android.net.Uri
import android.util.TypedValue
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
@ -149,4 +150,9 @@ fun View.showWithAnimation() {
isVisible = true isVisible = true
animate().cancel() animate().cancel()
animate().alpha(1f).start() animate().alpha(1f).start()
}
fun View.addCircleRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, this, true)
setBackgroundResource(resourceId)
} }

@ -215,7 +215,7 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour
override fun updateUIAfterUndoDeletion(newItem: RealmObject) { override fun updateUIAfterUndoDeletion(newItem: RealmObject) {
// TODO: Improve that // TODO: Improve that
// We are recreating a Bankroll report because the last one if invalid => the bankroll of the setup has been deleted // We are recreating a Bankroll report because the last one is invalid => the bankroll of the setup has been deleted
deletedRow?.let { row -> deletedRow?.let { row ->
val bankrollReportSetup = BankrollReportSetup(newItem as Bankroll) val bankrollReportSetup = BankrollReportSetup(newItem as Bankroll)

@ -93,9 +93,7 @@ class ComparisonChartFragment : PokerAnalyticsFragment(), StaticRowRepresentable
private fun initUI() { private fun initUI() {
setDisplayHomeAsUpEnabled(true) setDisplayHomeAsUpEnabled(true)
setToolbarTitle(getString(R.string.comparison_chart))
//TODO: Localize title
setToolbarTitle("Comparison chart")
parentActivity?.let { parentActivity?.let {
viewPagerAdapter = ComparisonChartPagerAdapter(requireContext(), it.supportFragmentManager) viewPagerAdapter = ComparisonChartPagerAdapter(requireContext(), it.supportFragmentManager)

@ -41,20 +41,6 @@ class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource
return this.items return this.items
} }
/**
* Set fragment data
*/
fun setData(dataType: Int) {
this.dataType = LiveData.values()[dataType]
this.identifiableClass = this.dataType.relatedEntity
setToolbarTitle(this.dataType.localizedTitle(requireContext()))
val realm = getRealm()
this.items = realm.sorted(this.identifiableClass)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState) super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_data_list, container, false) return inflater.inflate(R.layout.fragment_data_list, container, false)
@ -116,18 +102,21 @@ class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource
return if (viewType != -1) viewType else RowViewType.DATA.ordinal return if (viewType != -1) viewType else RowViewType.DATA.ordinal
} }
override fun indexForRow(row: RowRepresentable): Int {
return this.items.indexOf(row as Identifiable)
}
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
when (this.dataType) { when (this.dataType) {
LiveData.FILTER -> { LiveData.FILTER -> {
val intent = Intent() if (fromAction) {
intent.putExtra(FiltersActivity.IntentKey.FILTER_ID.keyName, (row as Filter).id) // Open filter params
activity?.setResult(Activity.RESULT_OK, intent) val filter = row as Filter
activity?.finish() FiltersActivity.newInstanceForResult(fragment = this, filterId = filter.id, currentFilterable = filter.filterableType)
} else {
// Select filter
val intent = Intent()
intent.putExtra(FiltersActivity.IntentKey.FILTER_ID.keyName, (row as Filter).id)
activity?.setResult(Activity.RESULT_OK, intent)
activity?.finish()
}
} }
else -> { else -> {
val identifier = (row as Identifiable).id val identifier = (row as Identifiable).id
@ -136,4 +125,29 @@ class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource
} }
} }
/**
* Set fragment data
*/
fun setData(dataType: Int) {
this.dataType = LiveData.values()[dataType]
this.identifiableClass = this.dataType.relatedEntity
setToolbarTitle(this.dataType.localizedTitle(requireContext()))
val realm = getRealm()
this.items = realm.sorted(this.identifiableClass)
}
/**
* Update UI
*/
fun updateUI(showAddButton: Boolean) {
if (showAddButton) {
this.addButton.show()
} else {
this.addButton.hide()
}
}
} }

@ -55,7 +55,6 @@ open class FilterDetailsFragment : RealmFragment(), StaticRowRepresentableDataSo
override fun onBackPressed() { override fun onBackPressed() {
super.onBackPressed() super.onBackPressed()
println("<<<<< back pressed")
saveData() saveData()
} }

@ -27,13 +27,13 @@ import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
import net.pokeranalytics.android.util.Preferences import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.extensions.sorted import net.pokeranalytics.android.util.extensions.sorted
import timber.log.Timber
open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate {
companion object { companion object {
const val REQUEST_CODE_FILTER_DETAILS = 100 const val REQUEST_CODE_FILTER_DETAILS = 100
const val MOST_USED_FILTERS_DISPLAYED = 6
var currentFilter: Filter? = null var currentFilter: Filter? = null
@ -156,7 +156,7 @@ open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource,
} }
moreFilters.setOnClickListener { moreFilters.setOnClickListener {
DataListActivity.newSelectInstance(this, LiveData.FILTER.ordinal) DataListActivity.newSelectInstance(this, LiveData.FILTER.ordinal, false)
} }
} }
@ -196,19 +196,19 @@ open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource,
*/ */
private fun updateMostUsedFilters() { private fun updateMostUsedFilters() {
if (isUpdating) { var nbChips = 0
val filters = getRealm().sorted(Filter::class.java)
val currentFilterId = Preferences.getActiveFilterId(requireContext())
if (isUpdating || filters.isEmpty() || (filters.size == 1 && filters.first()?.id == currentFilterId)) {
mostUsedFiltersLayout.visibility = View.GONE mostUsedFiltersLayout.visibility = View.GONE
return return
} }
val filters = getRealm().sorted(Filter::class.java)
val currentFilterId = Preferences.getActiveFilterId(requireContext())
mostUsedFilters.removeAllViews() mostUsedFilters.removeAllViews()
var nbChips = 0
filters.forEach { filter -> filters.forEach { filter ->
if (nbChips < 3) { if (nbChips < MOST_USED_FILTERS_DISPLAYED) {
if (filter.id != currentFilterId) { if (filter.id != currentFilterId) {
val chip = Chip(requireContext()) val chip = Chip(requireContext())
@ -220,7 +220,6 @@ open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource,
chip.isChecked = filter.id == currentFilterId chip.isChecked = filter.id == currentFilterId
chip.setOnCloseIconClickListener { chip.setOnCloseIconClickListener {
chip.isChecked = false chip.isChecked = false
} }
chip.setOnClickListener { chip.setOnClickListener {
@ -235,7 +234,6 @@ open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource,
} }
} }
} }
} }
/** /**
@ -250,13 +248,10 @@ open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource,
* Validate the updates of the queryWith * Validate the updates of the queryWith
*/ */
private fun validateUpdates() { private fun validateUpdates() {
Timber.d("Validate queryWith updates")
val realm = getRealm() val realm = getRealm()
realm.beginTransaction() realm.beginTransaction()
currentFilter?.let { currentFilter?.let {
it.name = it.query.getName(requireContext()) it.name = it.query.getName(requireContext())
Timber.d("name: ${it.name}")
realm.copyToRealmOrUpdate(it) realm.copyToRealmOrUpdate(it)
} }
realm.commitTransaction() realm.commitTransaction()
@ -269,10 +264,7 @@ open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource,
* Cancel the latest updates of the queryWith * Cancel the latest updates of the queryWith
*/ */
private fun cancelUpdates() { private fun cancelUpdates() {
Timber.d("Cancel queryWith updates")
val filterId = filterCopy?.id ?: "" val filterId = filterCopy?.id ?: ""
val realm = getRealm() val realm = getRealm()
realm.beginTransaction() realm.beginTransaction()
filterCopy?.let { filterCopy?.let {

@ -120,10 +120,6 @@ class ReportCreationFragment : RealmFragment(), RowRepresentableDataSource, RowR
} }
} }
override fun indexForRow(row: RowRepresentable): Int {
return this.currentRows.indexOf(row)
}
override fun isSelected(row: RowRepresentable): Boolean { override fun isSelected(row: RowRepresentable): Boolean {
return this.assistant.isSelected(row) return this.assistant.isSelected(row)
} }

@ -15,10 +15,8 @@ import kotlinx.coroutines.launch
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.interfaces.Deletable import net.pokeranalytics.android.model.interfaces.Deletable
import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.DataListActivity
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import timber.log.Timber
/** /**
* Deletable Item Fragment * Deletable Item Fragment
@ -89,10 +87,8 @@ abstract class DeletableItemFragment : RealmFragment() {
val deletableItem = (itemToDelete as Deletable) val deletableItem = (itemToDelete as Deletable)
Timber.d("deletableItem: ${(deletableItem as Filter).getDisplayName(requireContext())}")
// Check if the object is valid for the deletion // Check if the object is valid for the deletion
if (deletableItem.isValidForDelete(this.getRealm())) { if (deletableItem.isValidForDelete(requireContext(), this.getRealm())) {
deletedItem = getRealm().copyFromRealm(itemToDelete) deletedItem = getRealm().copyFromRealm(itemToDelete)
lastDeletedItemPosition = itemPosition lastDeletedItemPosition = itemPosition
getRealm().executeTransaction { getRealm().executeTransaction {
@ -104,7 +100,7 @@ abstract class DeletableItemFragment : RealmFragment() {
showUndoSnackBar() showUndoSnackBar()
} else { } else {
dataListAdapter.notifyItemChanged(itemPosition) dataListAdapter.notifyItemChanged(itemPosition)
val status = deletableItem.getDeleteStatus(this.getRealm()) val status = deletableItem.getDeleteStatus(requireContext(), this.getRealm())
val message = deletableItem.getFailedDeleteMessage(status) val message = deletableItem.getFailedDeleteMessage(status)
val builder = AlertDialog.Builder(requireContext()) val builder = AlertDialog.Builder(requireContext())
.setMessage(message) .setMessage(message)

@ -22,9 +22,9 @@ import timber.log.Timber
/** /**
* A class which define the fragment as Filterable * A class which define the fragment as Filterable
* - Add an filter icon menu * - Add a filter icon menu
* - Access to the filters actions (new, select, modify, remove) * - Listen for INTENT_FILTER_UPDATE_FILTER_UI
* - ... * -
*/ */
open class FilterableFragment : RealmFragment(), FilterHandler { open class FilterableFragment : RealmFragment(), FilterHandler {
@ -46,13 +46,11 @@ open class FilterableFragment : RealmFragment(), FilterHandler {
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState) super.onActivityCreated(savedInstanceState)
Timber.d("onActivityCreated: $parentActivity")
parentActivity?.registerReceiver(updateFilterUIBroadcast, IntentFilter(INTENT_FILTER_UPDATE_FILTER_UI)) parentActivity?.registerReceiver(updateFilterUIBroadcast, IntentFilter(INTENT_FILTER_UPDATE_FILTER_UI))
} }
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
Timber.d("onDestroy: $parentActivity")
parentActivity?.unregisterReceiver(updateFilterUIBroadcast) parentActivity?.unregisterReceiver(updateFilterUIBroadcast)
} }
@ -84,12 +82,10 @@ open class FilterableFragment : RealmFragment(), FilterHandler {
} }
override fun applyFilter() { override fun applyFilter() {
Timber.d("applyFilter")
updateFilterUI() updateFilterUI()
} }
override fun removeFilter() { override fun removeFilter() {
Timber.d("removeFilter")
hideSelectedFilter() hideSelectedFilter()
} }

@ -27,7 +27,6 @@ class BottomSheetDoubleEditTextFragment : BottomSheetFragment() {
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
if (isEditingBlinds) { if (isEditingBlinds) {
editText2.requestFocus() editText2.requestFocus()
} else { } else {
@ -43,6 +42,7 @@ class BottomSheetDoubleEditTextFragment : BottomSheetFragment() {
* Init data * Init data
*/ */
private fun initData() { private fun initData() {
valueHasPlaceholder = true
isEditingBlinds = row == SessionRow.BLINDS isEditingBlinds = row == SessionRow.BLINDS
} }
@ -64,17 +64,23 @@ class BottomSheetDoubleEditTextFragment : BottomSheetFragment() {
values[0] = (data[0].defaultValue ?: "").toString() values[0] = (data[0].defaultValue ?: "").toString()
values[1] = (data[1].defaultValue ?: "").toString() values[1] = (data[1].defaultValue ?: "").toString()
editText1.setText(values[0])
editText2.setText(values[1])
data[0].hint?.let { editText1.hint = getString(it) } data[0].hint?.let { editText1.hint = getString(it) }
editText1.inputType = data[0].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES editText1.inputType = data[0].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
data[1].hint?.let { editText2.hint = getString(it) }
editText2.inputType = data[1].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
if (valueHasPlaceholder) {
editText1.hint = values[0]
editText2.hint = values[1]
} else {
editText1.setText(values[0])
editText2.setText(values[1])
}
editText1.addTextChangedListener { editText1.addTextChangedListener {
values[0] = it?.toString() ?: "" values[0] = it?.toString() ?: ""
} }
data[1].hint?.let { editText2.hint = getString(it) }
editText2.inputType = data[1].inputType ?: InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
editText2.addTextChangedListener { editText2.addTextChangedListener {
values[1] = it?.toString() ?: "" values[1] = it?.toString() ?: ""
if (isEditingBlinds) { if (isEditingBlinds) {

@ -43,12 +43,14 @@ class BottomSheetEditTextFragment : BottomSheetFragment() {
* Init data * Init data
*/ */
private fun initData() { private fun initData() {
valueHasPlaceholder = true
} }
/** /**
* Init UI * Init UI
*/ */
private fun initUI() { private fun initUI() {
val data = getData()?:throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor not found") val data = getData()?:throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor not found")
if (data.size != 1) { if (data.size != 1) {
throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor inconsistency") throw RowRepresentableEditDescriptorException("RowRepresentableEditDescriptor inconsistency")
@ -62,7 +64,12 @@ class BottomSheetEditTextFragment : BottomSheetFragment() {
this.value = it?.toString() this.value = it?.toString()
} }
data[0].defaultValue?.let { data[0].defaultValue?.let {
editText1.setText(it.toString()) if (valueHasPlaceholder) {
this.value = it.toString()
editText1.hint = it.toString()
} else {
editText1.setText(it.toString())
}
} }
editText1.setOnEditorActionListener { _, actionId, _ -> editText1.setOnEditorActionListener { _, actionId, _ ->

@ -30,6 +30,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
lateinit var row: RowRepresentable lateinit var row: RowRepresentable
lateinit var delegate: RowRepresentableDelegate lateinit var delegate: RowRepresentableDelegate
var currentCurrency: Currency? = null var currentCurrency: Currency? = null
var valueHasPlaceholder: Boolean = false
private var isClearable: Boolean = true private var isClearable: Boolean = true
private var isDeletable: Boolean = false private var isDeletable: Boolean = false
@ -46,7 +47,8 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
rowRepresentableEditDescriptors: ArrayList<RowRepresentableEditDescriptor>?, rowRepresentableEditDescriptors: ArrayList<RowRepresentableEditDescriptor>?,
isClearable: Boolean? = true, isClearable: Boolean? = true,
currentCurrency: Currency? = null, currentCurrency: Currency? = null,
isDeletable: Boolean? = false isDeletable: Boolean? = false,
valueHasPlaceholder: Boolean? = false
): BottomSheetFragment { ): BottomSheetFragment {
val bottomSheetFragment = row.bottomSheetType.newInstance() val bottomSheetFragment = row.bottomSheetType.newInstance()
bottomSheetFragment.show(fragmentManager, "bottomSheet") bottomSheetFragment.show(fragmentManager, "bottomSheet")
@ -55,6 +57,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
bottomSheetFragment.rowRepresentableEditDescriptors = rowRepresentableEditDescriptors bottomSheetFragment.rowRepresentableEditDescriptors = rowRepresentableEditDescriptors
bottomSheetFragment.isClearable = isClearable ?: true bottomSheetFragment.isClearable = isClearable ?: true
bottomSheetFragment.isDeletable = isDeletable ?: true bottomSheetFragment.isDeletable = isDeletable ?: true
bottomSheetFragment.valueHasPlaceholder = valueHasPlaceholder ?: true
bottomSheetFragment.currentCurrency = currentCurrency bottomSheetFragment.currentCurrency = currentCurrency
return bottomSheetFragment return bottomSheetFragment
} }

@ -49,13 +49,6 @@ open class BottomSheetListFragment : BottomSheetFragment(), LiveRowRepresentable
return RowViewType.BOTTOM_SHEET_DATA.ordinal return RowViewType.BOTTOM_SHEET_DATA.ordinal
} }
override fun indexForRow(row: RowRepresentable): Int {
realmData?.let {
return it.indexOf(row)
}
throw IllegalStateException("Need to implement Data Source")
}
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
realmData?.let { realmData?.let {
val selectedData = it[position] val selectedData = it[position]

@ -24,7 +24,6 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.CustomFieldRow
import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow
import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.NULL_TEXT
import java.util.* import java.util.*
import kotlin.collections.ArrayList
/** /**
* Custom EditableDataFragment to manage the Transaction data * Custom EditableDataFragment to manage the Transaction data
@ -180,8 +179,8 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa
super.onRowDeleted(row) super.onRowDeleted(row)
when (row) { when (row) {
is CustomFieldEntry -> { is CustomFieldEntry -> {
if (!row.isValidForDelete(getRealm())) { if (!row.isValidForDelete(requireContext(), getRealm())) {
val status = row.getDeleteStatus(getRealm()) val status = row.getDeleteStatus(requireContext(), getRealm())
val message = row.getFailedDeleteMessage(status) val message = row.getFailedDeleteMessage(status)
showAlertDialog(requireContext(), R.string.cf_entry_delete_popup_title, message, showCancelButton = true, positiveAction = { showAlertDialog(requireContext(), R.string.cf_entry_delete_popup_title, message, showCancelButton = true, positiveAction = {
customField.deleteEntry(row) customField.deleteEntry(row)

@ -126,13 +126,13 @@ open class DataManagerFragment : RealmFragment() {
val deletable = this.item as Deletable val deletable = this.item as Deletable
val realm = this.getRealm() val realm = this.getRealm()
if (deletable.isValidForDelete(realm)) { if (deletable.isValidForDelete(requireContext(), realm)) {
val intent = Intent() val intent = Intent()
intent.putExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName, deletable.id) intent.putExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName, deletable.id)
activity?.setResult(Activity.RESULT_OK, intent) activity?.setResult(Activity.RESULT_OK, intent)
activity?.finish() activity?.finish()
} else { } else {
val status = deletable.getDeleteStatus(realm) val status = deletable.getDeleteStatus(requireContext(), realm)
val message = deletable.getFailedDeleteMessage(status) val message = deletable.getFailedDeleteMessage(status)
val builder = AlertDialog.Builder(requireContext()) val builder = AlertDialog.Builder(requireContext())
.setMessage(message) .setMessage(message)

@ -65,11 +65,9 @@ open class EditableDataFragment : DataManagerFragment(), RowRepresentableDelegat
val proxyItem: RealmModel? = this.liveDataType.getData(this.getRealm(), primaryKey) val proxyItem: RealmModel? = this.liveDataType.getData(this.getRealm(), primaryKey)
proxyItem?.let { proxyItem?.let {
//TODO: Localize this.appBar.toolbar.title = this.liveDataType.updateEntityLocalizedTitle(requireContext())
this.appBar.toolbar.title = "Update ${this.liveDataType.localizedTitle(requireContext()).toLowerCase().capitalize()}"
deleteButtonShouldAppear = true deleteButtonShouldAppear = true
} ?: run { } ?: run {
//TODO: Localize
this.appBar.toolbar.title = this.liveDataType.newEntityLocalizedTitle(requireContext()) this.appBar.toolbar.title = this.liveDataType.newEntityLocalizedTitle(requireContext())
} }

@ -57,54 +57,6 @@ interface FilterHandler {
* Manage filters * Manage filters
*/ */
fun manageFilters(fragment: Fragment) { fun manageFilters(fragment: Fragment) {
val context = fragment.requireContext()
val filterId = Preferences.getActiveFilterId(context)
FiltersActivity.newInstanceForResult(fragment = fragment, currentFilterable = currentFilterable) FiltersActivity.newInstanceForResult(fragment = fragment, currentFilterable = currentFilterable)
//TODO: Clean
/*
val filterSelected = filterId != null
val realm = Realm.getDefaultInstance()
val count = realm.where<Filter>().count().toInt()
realm.close()
val choices = ArrayList<CharSequence>()
choices.add(fragment.getString(R.string.new_str))
if (count > 0) {
choices.add(fragment.getString(R.string.load_from_db))
}
if (filterSelected) {
choices.add(fragment.getString(R.string.modify_current_filter))
choices.add(fragment.getString(R.string.remove_filter))
}
val builder = AlertDialog.Builder(context)
builder.setTitle(R.string.filter_selection)
.setCancelable(true)
.setItems(choices.toTypedArray()) { _, which ->
Timber.d("Click on $which")
when (which) {
0 -> FiltersActivity.newInstanceForResult(fragment = fragment, currentFilterable = currentFilterable)
1 -> DataListActivity.newSelectInstance(fragment, LiveData.FILTER.ordinal)
2 -> FiltersActivity.newInstanceForResult(fragment = fragment, filterId = filterId, currentFilterable = currentFilterable)
3 -> {
Preferences.removeActiveFilterId(context)
filterWasUpdated = true
removeFilter()
}
}
}
.setNegativeButton(R.string.cancel) { _, _ ->
Timber.d("Click on cancel")
}
builder.show()
*/
} }
} }

@ -34,15 +34,13 @@ interface DefaultEditDataSource : EditDataSource, Localizable {
interface ImageDecorator { interface ImageDecorator {
val imageRes: Int? val imageRes: Int?
get() { get() = null
return null
}
val imageTint: Int? val imageTint: Int?
get() { get() = null
return null
}
val imageClickable: Boolean?
get() = false
} }
/** /**

@ -31,6 +31,7 @@ import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.Transaction import net.pokeranalytics.android.model.realm.Transaction
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.extensions.ChipGroupExtension import net.pokeranalytics.android.ui.extensions.ChipGroupExtension
import net.pokeranalytics.android.ui.extensions.addCircleRipple
import net.pokeranalytics.android.ui.extensions.px import net.pokeranalytics.android.ui.extensions.px
import net.pokeranalytics.android.ui.extensions.setTextFormat import net.pokeranalytics.android.ui.extensions.setTextFormat
import net.pokeranalytics.android.ui.graph.AxisFormatting import net.pokeranalytics.android.ui.graph.AxisFormatting
@ -204,6 +205,14 @@ enum class RowViewType(private var layoutRes: Int) {
row.imageTint?.let { color -> row.imageTint?.let { color ->
imageView.setColorFilter(ContextCompat.getColor(imageView.context, color)) imageView.setColorFilter(ContextCompat.getColor(imageView.context, color))
} }
if (row.imageClickable == true) {
imageView.addCircleRipple()
imageView.setOnClickListener {
adapter.delegate?.onRowSelected(position, row, true)
}
} else {
imageView.setBackgroundResource(0)
}
} }
// Listener // Listener

@ -61,6 +61,8 @@
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:paddingBottom="72dp"
android:clipToPadding="false"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

@ -1,66 +1,79 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container" android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="48dp">
android:background="?selectableItemBackground">
<androidx.appcompat.widget.AppCompatTextView <include layout="@layout/layout_swipe_to_delete" />
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/guidelineStart"
app:layout_constraintTop_toTopOf="parent"
tools:text="Title" />
<androidx.appcompat.widget.AppCompatTextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/value" android:id="@+id/foreground"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginStart="16dp" android:background="@color/gray_dark"
android:ellipsize="end" android:foreground="?selectableItemBackground">
android:gravity="end|center_vertical"
android:maxLines="1"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/action"
app:layout_constraintStart_toEndOf="@+id/title"
app:layout_constraintTop_toTopOf="parent"
tools:text="Value" />
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/action" android:id="@+id/title"
android:layout_width="32dp" android:layout_width="wrap_content"
android:layout_height="32dp" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginTop="16dp"
android:padding="4dp" android:layout_marginBottom="16dp"
android:visibility="gone" android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/guidelineEnd" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/value" app:layout_constraintStart_toStartOf="@+id/guidelineStart"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_close" /> tools:text="Title" />
<androidx.constraintlayout.widget.Guideline <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/guidelineStart" android:id="@+id/value"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:layout_marginStart="16dp"
app:layout_constraintGuide_begin="16dp" /> android:layout_marginEnd="8dp"
android:ellipsize="end"
android:gravity="end|center_vertical"
android:maxLines="1"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/action"
app:layout_constraintStart_toEndOf="@+id/title"
app:layout_constraintTop_toTopOf="parent"
tools:text="Value" />
<androidx.constraintlayout.widget.Guideline <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/guidelineEnd" android:id="@+id/action"
android:layout_width="wrap_content" android:layout_width="32dp"
android:layout_height="wrap_content" android:layout_height="32dp"
android:orientation="vertical" android:background="?selectableItemBackgroundBorderless"
app:layout_constraintGuide_end="16dp" /> android:padding="4dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/guidelineEnd"
app:layout_constraintStart_toEndOf="@+id/value"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_close"
tools:visibility="visible" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="16dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineEnd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="8dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -31,7 +31,13 @@
<string name="launch_report">Launch Report</string> <string name="launch_report">Launch Report</string>
<string name="progress">Progress</string> <string name="progress">Progress</string>
<string name="save_report">Save Report</string> <string name="save_report">Save Report</string>
<<<<<<< HEAD
<string name="import_confirmation">Do you want to proceed with the file import?</string> <string name="import_confirmation">Do you want to proceed with the file import?</string>
=======
<string name="update_entity" formatted="false">Update %s</string>
<string name="comparison_chart">Comparison chart</string>
<string name="filter_currently_selected">The filter cannot be deleted because it is currently selected.</string>
>>>>>>> 5d02ab88722ad9a85d1b7d57dac44a54369a9b74
<string name="address">Address</string> <string name="address">Address</string>
<string name="suggestions">Naming suggestions</string> <string name="suggestions">Naming suggestions</string>

Loading…
Cancel
Save