From b06bcb976c3f85f35469390887a55e5ab9d464dd Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 09:00:18 +0200 Subject: [PATCH 01/21] Add image tint --- .../net/pokeranalytics/android/ui/view/RowRepresentable.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt index 8eedb85a..15212620 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt @@ -37,6 +37,12 @@ interface ImageDecorator { get() { return null } + + val imageTint: Int? + get() { + return null + } + } /** From 3ea88169bb1c80b59e6c150f27cbbbe8ae5ede7a Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 09:00:24 +0200 Subject: [PATCH 02/21] Improve custom field UI --- .../android/model/realm/CustomFieldEntry.kt | 12 +++++++++++- .../ui/fragment/data/CustomFieldDataFragment.kt | 1 + .../pokeranalytics/android/ui/view/RowViewType.kt | 15 ++++++++++++++- .../main/res/layout/row_title_value_action.xml | 3 +-- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt index 1fdc9a7e..21122f2c 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt @@ -22,7 +22,17 @@ open class CustomFieldEntry : RealmObject(), RowRepresentable { var order: Int = 0 @Ignore - override val viewType: Int = RowViewType.TITLE.ordinal + override val viewType: Int = RowViewType.TITLE_VALUE_ACTION.ordinal + + override val imageRes: Int? + get() { + return R.drawable.ic_reorder + } + + override val imageTint: Int? + get() { + return R.color.kaki + } @Ignore override val bottomSheetType: BottomSheetType = BottomSheetType.EDIT_TEXT diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt index e5b4d65d..424f8431 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt @@ -165,6 +165,7 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa updateUI() updateAdapterUI() } + else -> super.onRowValueChanged(value, row) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt index d78ec10b..2f857f0f 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt @@ -8,6 +8,7 @@ import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatTextView import androidx.appcompat.widget.SwitchCompat import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.core.widget.ContentLoadingProgressBar import androidx.recyclerview.widget.RecyclerView @@ -64,6 +65,7 @@ enum class RowViewType(private var layoutRes: Int) { TITLE_ICON_ARROW(R.layout.row_title_icon_arrow), TITLE_VALUE(R.layout.row_title_value), TITLE_VALUE_ARROW(R.layout.row_title_value_arrow), + TITLE_VALUE_ACTION(R.layout.row_title_value_action), TITLE_SWITCH(R.layout.row_title_switch), TITLE_GRID(R.layout.row_bottom_sheet_grid_title), DATA(R.layout.row_title), @@ -97,7 +99,7 @@ enum class RowViewType(private var layoutRes: Int) { // Row View Holder HEADER_TITLE, HEADER_TITLE_VALUE, HEADER_TITLE_AMOUNT, HEADER_TITLE_AMOUNT_BIG, LOCATION_TITLE, - INFO, TITLE, TITLE_ARROW, TITLE_ICON_ARROW, TITLE_VALUE, TITLE_VALUE_ARROW, TITLE_GRID, + INFO, TITLE, TITLE_ARROW, TITLE_ICON_ARROW, TITLE_VALUE, TITLE_VALUE_ARROW, TITLE_VALUE_ACTION, TITLE_GRID, TITLE_SWITCH, TITLE_CHECK, TITLE_VALUE_CHECK, DATA, BOTTOM_SHEET_DATA, LOADER -> RowViewHolder(layout) @@ -191,6 +193,17 @@ enum class RowViewType(private var layoutRes: Int) { } } + // Action + itemView.findViewById(R.id.action)?.let { imageView -> + row.imageRes?.let { imageRes -> + imageView.visibility = View.VISIBLE + imageView.setImageResource(imageRes) + } + row.imageTint?.let { color -> + imageView.setColorFilter(ContextCompat.getColor(imageView.context, color)) + } + } + // Listener val listener = View.OnClickListener { itemView.findViewById(R.id.switchView)?.let { diff --git a/app/src/main/res/layout/row_title_value_action.xml b/app/src/main/res/layout/row_title_value_action.xml index 4e26243f..b0e98b29 100644 --- a/app/src/main/res/layout/row_title_value_action.xml +++ b/app/src/main/res/layout/row_title_value_action.xml @@ -13,7 +13,7 @@ android:layout_height="wrap_content" android:layout_marginTop="16dp" android:layout_marginBottom="16dp" - android:textSize="18sp" + android:textSize="16sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="@+id/guidelineStart" @@ -40,7 +40,6 @@ android:layout_width="32dp" android:layout_height="32dp" android:layout_marginStart="16dp" - android:background="?selectableItemBackgroundBorderless" android:padding="4dp" android:visibility="gone" app:layout_constraintBottom_toBottomOf="parent" From a23f23fb7c29b317c0e4ff5ca407990c68b461d1 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 12:45:40 +0200 Subject: [PATCH 03/21] Update gradle version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8a1c4fe4..0340e807 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { } } dependencies { - classpath 'com.android.tools.build:gradle:3.4.0' + classpath 'com.android.tools.build:gradle:3.4.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'io.realm:realm-gradle-plugin:5.8.0' classpath 'com.google.gms:google-services:4.2.0' From 3b077e693fe74811119b50c3baadb3f6fbcbe26e Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 12:46:27 +0200 Subject: [PATCH 04/21] Add delete action for BottomSheet --- .../android/ui/adapter/RowRepresentableAdapter.kt | 1 + .../components/bottomsheet/BottomSheetFragment.kt | 13 ++++++++++++- app/src/main/res/menu/toolbar_bottom_sheet.xml | 10 +++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableAdapter.kt index 787c0dac..f712f987 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableAdapter.kt @@ -10,6 +10,7 @@ import net.pokeranalytics.android.ui.view.RowViewType interface RowRepresentableDelegate { fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean = false) {} fun onRowValueChanged(value: Any?, row: RowRepresentable) {} + fun onRowDeleted(row: RowRepresentable) {} } /** diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt index f883c7f2..8f38bf64 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt @@ -32,6 +32,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() { var currentCurrency: Currency? = null private var isClearable: Boolean = true + private var isDeletable: Boolean = false private var rowRepresentableEditDescriptors: ArrayList? = null companion object { @@ -44,7 +45,8 @@ open class BottomSheetFragment : BottomSheetDialogFragment() { delegate: RowRepresentableDelegate, rowRepresentableEditDescriptors: ArrayList?, isClearable: Boolean? = true, - currentCurrency: Currency? = null + currentCurrency: Currency? = null, + isDeletable: Boolean? = false ): BottomSheetFragment { val bottomSheetFragment = row.bottomSheetType.newInstance() bottomSheetFragment.show(fragmentManager, "bottomSheet") @@ -52,6 +54,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() { bottomSheetFragment.delegate = delegate bottomSheetFragment.rowRepresentableEditDescriptors = rowRepresentableEditDescriptors bottomSheetFragment.isClearable = isClearable ?: true + bottomSheetFragment.isDeletable = isDeletable ?: true bottomSheetFragment.currentCurrency = currentCurrency return bottomSheetFragment } @@ -111,6 +114,13 @@ open class BottomSheetFragment : BottomSheetDialogFragment() { dismiss() true } + + bottomSheetToolbar.menu.findItem(R.id.actionDelete).setOnMenuItemClickListener { + delegate.onRowDeleted(row) + dismiss() + true + } + bottomSheetToolbar.menu.findItem(R.id.actionAdd).setOnMenuItemClickListener { when (row) { SessionRow.GAME -> EditableDataActivity.newInstanceForResult( @@ -153,6 +163,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() { } bottomSheetToolbar.menu.findItem(R.id.actionClear).isVisible = isClearable + bottomSheetToolbar.menu.findItem(R.id.actionDelete).isVisible = isDeletable } } diff --git a/app/src/main/res/menu/toolbar_bottom_sheet.xml b/app/src/main/res/menu/toolbar_bottom_sheet.xml index 836d374c..7ef0e761 100644 --- a/app/src/main/res/menu/toolbar_bottom_sheet.xml +++ b/app/src/main/res/menu/toolbar_bottom_sheet.xml @@ -2,11 +2,18 @@ + + \ No newline at end of file From 7d17287e65dd6a799113962553be9b4853779df1 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 12:46:48 +0200 Subject: [PATCH 05/21] Update models and migration --- .../migrations/PokerAnalyticsMigration.kt | 1 + .../android/model/realm/CustomField.kt | 60 ++++++++++++++----- .../android/model/realm/CustomFieldEntry.kt | 5 +- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index 9e300e87..a97162e2 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -110,6 +110,7 @@ class PokerAnalyticsMigration : RealmMigration { schema.get("CustomField")?.let { it.addField("type", Integer::class.java).setNullable("type", false) it.addField("duplicateValue", Boolean::class.java) + it.addField("sortCondition", Integer::class.java) it.addRealmListField("entries", CustomFieldEntry::class.java) } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt index e8c6188b..8db3fc0b 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt @@ -17,6 +17,7 @@ import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.rowrepresentable.CustomFieldRow import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow +import net.pokeranalytics.android.util.enumerations.IntIdentifiable import timber.log.Timber import java.util.* import kotlin.collections.ArrayList @@ -24,10 +25,16 @@ import kotlin.collections.ArrayList open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDataSource, RowRepresentable { - enum class Type(var resId: Int) { - LIST(R.string.enum_custom_field_type), - NUMBER(R.string.number), - AMOUNT(R.string.amount) + enum class Type(override var uniqueIdentifier: Int, var resId: Int) : IntIdentifiable { + LIST(0, R.string.enum_custom_field_type), + NUMBER(1, R.string.number), + AMOUNT(2, R.string.amount) + } + + enum class Sort(override var uniqueIdentifier: Int) : IntIdentifiable { + DEFAULT(0), + ASCENDING(1), + DESCENDING(2) } @PrimaryKey @@ -37,7 +44,7 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa override var name: String = "" // Migration - var type: Int = Type.LIST.ordinal + var type: Int = Type.LIST.uniqueIdentifier set(value) { field = value this.updateRowRepresentation() @@ -45,10 +52,14 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa var duplicateValue: Boolean = false var entries: RealmList = RealmList() + var sortCondition: Int = Sort.DEFAULT.uniqueIdentifier + set(value) { + field = value + sortEntries() + updateRowRepresentation() + } - // @todo - override fun getDisplayName(context: Context): String { return this.name } @@ -106,6 +117,9 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa } } + /** + * Update the row representation + */ private fun updatedRowRepresentationForCurrentState(): List { val rows = ArrayList() rows.add(SimpleRow.NAME) @@ -114,8 +128,10 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa if (type == Type.LIST.ordinal && entries.size >= 0) { rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, R.string.items_list)) if (entries.isNotEmpty()) { - Timber.d("entries: ${entries.size}") - entries.sortBy { it.order } + sortEntries() + entries.forEach { customFieldEntry -> + customFieldEntry.isMovable = sortCondition == Sort.DEFAULT.uniqueIdentifier + } rows.addAll(entries) } } @@ -124,25 +140,41 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa return rows } + /** + * Sort the entries element + */ + private fun sortEntries() { + when (sortCondition) { + Sort.ASCENDING.uniqueIdentifier -> entries.sortBy { it.value } + Sort.DESCENDING.uniqueIdentifier -> entries.sortByDescending { it.value } + } + entries.forEachIndexed { index, customFieldEntry -> + customFieldEntry.order = index + } + } + fun updateRowRepresentation() { this.rowRepresentation = this.updatedRowRepresentationForCurrentState() } /** - * Add entry + * Add an entry */ fun addEntry() { val entry = CustomFieldEntry() - entry.order = (entries.lastOrNull()?.order ?: 0) + 1 entries.add(entry) + sortEntries() updateRowRepresentation() } /** - * + * Delete an entry */ - fun deleteEntry() { - + fun deleteEntry(entry: CustomFieldEntry) { + entries.remove(entry) + sortEntries() + updateRowRepresentation() } + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt index 21122f2c..6c17e556 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt @@ -21,12 +21,15 @@ open class CustomFieldEntry : RealmObject(), RowRepresentable { var value: String = "" var order: Int = 0 + @Ignore + var isMovable: Boolean = false + @Ignore override val viewType: Int = RowViewType.TITLE_VALUE_ACTION.ordinal override val imageRes: Int? get() { - return R.drawable.ic_reorder + return if (isMovable) R.drawable.ic_reorder else null } override val imageTint: Int? From 89730eae9cda3ebd93cec849f231031bd060ed23 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 12:47:00 +0200 Subject: [PATCH 06/21] Improve custom field management --- .../ui/adapter/RowRepresentableAdapter.kt | 3 + .../fragment/data/CustomFieldDataFragment.kt | 86 ++++++++++++------- .../ui/fragment/data/EditableDataFragment.kt | 1 + .../android/ui/view/RowViewType.kt | 2 + app/src/main/res/drawable/ic_list.xml | 9 ++ .../main/res/layout/fragment_custom_view.xml | 31 +++++++ 6 files changed, 102 insertions(+), 30 deletions(-) create mode 100644 app/src/main/res/drawable/ic_list.xml diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableAdapter.kt index f712f987..29237a74 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableAdapter.kt @@ -55,10 +55,13 @@ class RowRepresentableAdapter( return } + /* val index = this.dataSource.indexForRow(row) if (index >= 0) { notifyItemChanged(index) } + */ + notifyDataSetChanged() } /** diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt index 424f8431..e1b1eae6 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt @@ -7,12 +7,14 @@ import android.view.ViewGroup 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.model.realm.CustomField import net.pokeranalytics.android.model.realm.CustomFieldEntry 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.fragment.components.bottomsheet.BottomSheetFragment import net.pokeranalytics.android.ui.view.RowRepresentable @@ -22,6 +24,7 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow import net.pokeranalytics.android.util.NULL_TEXT import timber.log.Timber import java.util.* +import kotlin.collections.ArrayList /** * Custom EditableDataFragment to manage the Transaction data @@ -35,7 +38,7 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa } private val oldRows: ArrayList = ArrayList() - + private val currentEntriesOrder: ArrayList = ArrayList() private val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() { @@ -54,6 +57,7 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa } override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean { + if (target.adapterPosition <= 2) { return false } @@ -147,7 +151,7 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa is CustomFieldEntry -> { val data = customField.editDescriptors(row) Timber.d("data: $data") - BottomSheetFragment.create(fragmentManager, row, this, data, false) + BottomSheetFragment.create(fragmentManager, row, this, data, isClearable = false, isDeletable = true) } else -> super.onRowSelected(position, row, fromAction) } @@ -158,16 +162,26 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa when (row) { is CustomFieldEntry -> { row.value = value as String? ?: "" - rowRepresentableAdapter.refreshRow(row) + customField.updateRowRepresentation() + rowRepresentableAdapter.notifyDataSetChanged() } CustomFieldRow.TYPE -> { customField.updateValue(value, row) updateUI() - updateAdapterUI() + rowRepresentableAdapter.notifyDataSetChanged() } else -> super.onRowValueChanged(value, row) } + } + override fun onRowDeleted(row: RowRepresentable) { + super.onRowDeleted(row) + when (row) { + is CustomFieldEntry -> { + customField.deleteEntry(row) + rowRepresentableAdapter.notifyDataSetChanged() + } + } } /** @@ -178,15 +192,50 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa bottomBar.translationY = 72f.px bottomBar.visibility = View.VISIBLE - itemTouchHelper.attachToRecyclerView(recyclerView) + if (customField.sortCondition == CustomField.Sort.DEFAULT.uniqueIdentifier) { + itemTouchHelper.attachToRecyclerView(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 + } addItem.setOnClickListener { customField.addEntry() - updateAdapterUI() + rowRepresentableAdapter.notifyDataSetChanged() } + sortChoices.setOnCheckedChangeListener(object : ChipGroupExtension.SingleSelectionOnCheckedListener() { + override fun onCheckedChanged(group: ChipGroup, checkedId: Int) { + super.onCheckedChanged(group, checkedId) + + @SuppressWarnings + if (checkedId < 0) { // when unchecked, checkedId returns -1, causing a crash + return + } + + when(checkedId) { + R.id.sortDefault -> customField.sortCondition = CustomField.Sort.DEFAULT.uniqueIdentifier + R.id.sortAscending -> customField.sortCondition = CustomField.Sort.ASCENDING.uniqueIdentifier + R.id.sortDescending -> customField.sortCondition = CustomField.Sort.DESCENDING.uniqueIdentifier + } + + if (customField.sortCondition == CustomField.Sort.DEFAULT.uniqueIdentifier) { + itemTouchHelper.attachToRecyclerView(recyclerView) + } else { + itemTouchHelper.attachToRecyclerView(null) + } + rowRepresentableAdapter.notifyDataSetChanged() + } + }) + updateUI() - updateAdapterUI() + rowRepresentableAdapter.notifyDataSetChanged() + } /** @@ -204,27 +253,4 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa } } - /** - * Update adapter UI - */ - private fun updateAdapterUI() { - rowRepresentableAdapter.notifyDataSetChanged() - /* - //TODO: Code to animate changes - - // Test: - // not really, i agree with your part about performance but notifyDataSetChanged() does not kill animations, - // to animate using notifyDataSetChanged(), a) call setHasStableIds(true) on your RecyclerView.Adapter object and b) - // override getItemId inside your Adapter to return a unique long value for each row and check it out, the animations do work - - customField.adapterRows()?.let { - val diffResult = DiffUtil.calculateDiff(RowRepresentableDiffCallback(it, oldRows)) - rowRepresentableAdapter.updateRows(diffResult) - - oldRows.clear() - oldRows.addAll(it) - } - */ - } - } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/EditableDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/EditableDataFragment.kt index 5d3d6148..d9a131a8 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/EditableDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/EditableDataFragment.kt @@ -123,6 +123,7 @@ open class EditableDataFragment : RealmFragment(), RowRepresentableDelegate { val dataSource = getDataSource() this.rowRepresentableAdapter = RowRepresentableAdapter(getDataSource(), this) + this.rowRepresentableAdapter.setHasStableIds(true) this.recyclerView.adapter = rowRepresentableAdapter // When creating an object, open automatically the keyboard for the first row diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt index 2f857f0f..efa3a5c2 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt @@ -188,6 +188,7 @@ enum class RowViewType(private var layoutRes: Int) { // Icon itemView.findViewById(R.id.icon)?.let { imageView -> + imageView.setImageDrawable(null) row.imageRes?.let { imageRes -> imageView.setImageResource(imageRes) } @@ -195,6 +196,7 @@ enum class RowViewType(private var layoutRes: Int) { // Action itemView.findViewById(R.id.action)?.let { imageView -> + imageView.setImageDrawable(null) row.imageRes?.let { imageRes -> imageView.visibility = View.VISIBLE imageView.setImageResource(imageRes) diff --git a/app/src/main/res/drawable/ic_list.xml b/app/src/main/res/drawable/ic_list.xml new file mode 100644 index 00000000..4c2fb883 --- /dev/null +++ b/app/src/main/res/drawable/ic_list.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/fragment_custom_view.xml b/app/src/main/res/layout/fragment_custom_view.xml index 1ccb0e2f..e06f0ab9 100644 --- a/app/src/main/res/layout/fragment_custom_view.xml +++ b/app/src/main/res/layout/fragment_custom_view.xml @@ -65,6 +65,7 @@ android:layout_gravity="bottom" android:visibility="gone" app:contentInsetStart="8dp" + app:contentInsetEnd="8dp" tools:visibility="visible"> + + + + + + + + + + From 166bc814f1c0524a6294bd2a8cc060f349b84a66 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 12:50:46 +0200 Subject: [PATCH 07/21] Open automatically the bottom sheet --- .../net/pokeranalytics/android/model/realm/CustomField.kt | 3 ++- .../android/ui/fragment/data/CustomFieldDataFragment.kt | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt index 8db3fc0b..8ad64d7a 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt @@ -160,11 +160,12 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa /** * Add an entry */ - fun addEntry() { + fun addEntry(): CustomFieldEntry { val entry = CustomFieldEntry() entries.add(entry) sortEntries() updateRowRepresentation() + return entry } /** diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt index e1b1eae6..07401dde 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt @@ -150,7 +150,6 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa when (row) { is CustomFieldEntry -> { val data = customField.editDescriptors(row) - Timber.d("data: $data") BottomSheetFragment.create(fragmentManager, row, this, data, isClearable = false, isDeletable = true) } else -> super.onRowSelected(position, row, fromAction) @@ -205,8 +204,9 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa } addItem.setOnClickListener { - customField.addEntry() + val customFieldEntry = customField.addEntry() rowRepresentableAdapter.notifyDataSetChanged() + onRowSelected(-1, customFieldEntry) } sortChoices.setOnCheckedChangeListener(object : ChipGroupExtension.SingleSelectionOnCheckedListener() { From b23591e05cf1e4048ea1263d4b1692452d6678d9 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 12:54:24 +0200 Subject: [PATCH 08/21] Clean code --- .../java/net/pokeranalytics/android/model/realm/CustomField.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt index 8ad64d7a..a1876108 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt @@ -18,7 +18,6 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.CustomFieldRow import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow import net.pokeranalytics.android.util.enumerations.IntIdentifiable -import timber.log.Timber import java.util.* import kotlin.collections.ArrayList @@ -136,7 +135,6 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa } } - Timber.d("rows: ${rows.size}") return rows } From d0743a9dfde39f0cfadfe14d714b044cd1d29e63 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Wed, 15 May 2019 11:37:30 +0200 Subject: [PATCH 09/21] add transaction filtering management --- .../migrations/PokerAnalyticsMigration.kt | 5 ++- .../android/model/realm/Filter.kt | 14 +++++++- .../android/ui/fragment/FeedFragment.kt | 36 ++++++++++++++----- .../android/ui/fragment/FiltersFragment.kt | 2 +- 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index a97162e2..a2b336ed 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -127,7 +127,10 @@ class PokerAnalyticsMigration : RealmMigration { it.addField("startDateHourMinuteComponent", Double::class.java).setNullable("startDateHourMinuteComponent", true) it.addField("endDateHourMinuteComponent", Double::class.java).setNullable("endDateHourMinuteComponent", true) } - currentVersion++ + + schema.get("Filter")?.addField("filterableTypeOrdinal", Integer::class.java) + + currentVersion++ } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt index 8baf5a00..70478fd9 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt @@ -7,6 +7,7 @@ import io.realm.kotlin.where import net.pokeranalytics.android.model.filter.Filterable import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition +import net.pokeranalytics.android.ui.interfaces.FilterableType import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow import java.util.* @@ -21,8 +22,9 @@ open class Filter : RealmObject(), RowRepresentable { companion object { // Create a new instance - fun newInstance(realm: Realm): Filter { + fun newInstance(realm: Realm, filterableType:Int): Filter { val filter = Filter() + filter.filterableTypeOrdinal = filterableType return realm.copyToRealm(filter) } @@ -59,6 +61,16 @@ open class Filter : RealmObject(), RowRepresentable { var filterConditions: RealmList = RealmList() private set + private var filterableTypeOrdinal: Int? = null + + val filterableType: FilterableType + get() { + this.filterableTypeOrdinal?.let { + return FilterableType.values()[it] + } + return FilterableType.ALL + } + fun createOrUpdateFilterConditions(filterConditionRows: ArrayList) { println("list of querys saving: ${filterConditionRows.map { it.id }}") println("list of querys previous: ${this.filterConditions.map { it.queryCondition.id }}") diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt index c216bce8..19420e68 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt @@ -18,7 +18,6 @@ import io.realm.kotlin.where import kotlinx.android.synthetic.main.fragment_feed.* import net.pokeranalytics.android.R import net.pokeranalytics.android.model.LiveData -import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.interfaces.Editable import net.pokeranalytics.android.model.realm.Filter import net.pokeranalytics.android.model.realm.Session @@ -138,8 +137,14 @@ class FeedFragment : RealmFragment(), RowRepresentableDelegate, FilterHandler { tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { override fun onTabSelected(tab: TabLayout.Tab) { when (tab.position) { - 0 -> recyclerView.adapter = feedSessionAdapter - 1 -> recyclerView.adapter = feedTransactionAdapter + 0 -> { + currentFilterable = FilterableType.SESSION + recyclerView.adapter = feedSessionAdapter + } + 1 -> { + currentFilterable = FilterableType.TRANSACTION + recyclerView.adapter = feedTransactionAdapter + } } } @@ -162,27 +167,42 @@ class FeedFragment : RealmFragment(), RowRepresentableDelegate, FilterHandler { betaLimitDate = sdf.parse("17/7/2019 10:00") val filter : Filter? = this.currentFilter(this.requireContext(), getRealm()) + val sessionFilter: Filter? = filter?.let { + if (it.filterableType == FilterableType.SESSION) { + it + } else { + null + } + } + + val transactionFilter: Filter? = filter?.let { + if (it.filterableType == FilterableType.TRANSACTION) { + it + } else { + null + } + } // Sessions - this.realmSessions = filter?.results() ?: run { getRealm().where().findAll() }.sort("startDate", Sort.DESCENDING) + this.realmSessions = sessionFilter?.results() ?: run { getRealm().where().findAll() }.sort("startDate", Sort.DESCENDING) this.realmSessions.addChangeListener { _, _ -> this.feedSessionAdapter.refreshData() this.feedSessionAdapter.notifyDataSetChanged() } - val pendingSessions = filter?.let { getRealm().where().alwaysFalse().findAll() } ?: run { getRealm().where().isNull("year").isNull("month").findAll().sort("startDate", Sort.DESCENDING) } - val distinctDateSessions = filter?.results("year", "month") ?: run { getRealm().where().distinct("year", "month").findAll() }.sort("startDate", Sort.DESCENDING) + val pendingSessions = sessionFilter?.let { getRealm().where().alwaysFalse().findAll() } ?: run { getRealm().where().isNull("year").isNull("month").findAll().sort("startDate", Sort.DESCENDING) } + val distinctDateSessions = sessionFilter?.results("year", "month") ?: run { getRealm().where().distinct("year", "month").findAll() }.sort("startDate", Sort.DESCENDING) this.feedSessionAdapter = FeedSessionRowRepresentableAdapter(this, realmSessions, pendingSessions, distinctDateSessions) // Transactions - this.realmTransactions = getRealm().where().findAll().sort("date", Sort.DESCENDING) + this.realmTransactions = transactionFilter?.results() ?: run { getRealm().where().findAll()}.sort("date", Sort.DESCENDING) this.realmTransactions.addChangeListener { _, _ -> this.feedTransactionAdapter.refreshData() this.feedTransactionAdapter.notifyDataSetChanged() } - val distinctDateTransactions = getRealm().where().distinct("year", "month").findAll().sort("date", Sort.DESCENDING) + val distinctDateTransactions = transactionFilter?.results("year", "month") ?: run { getRealm().where().distinct("year", "month").findAll() }.sort("date", Sort.DESCENDING) this.feedTransactionAdapter = FeedTransactionRowRepresentableAdapter(this, realmTransactions, distinctDateTransactions) val viewManager = SmoothScrollLinearLayoutManager(requireContext()) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt index 9aeb056d..31741212 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt @@ -158,7 +158,7 @@ open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource, isUpdating = true } ?: run { realm.beginTransaction() - currentFilter = Filter.newInstance(realm) + currentFilter = Filter.newInstance(realm, this.filterableType.ordinal) realm.commitTransaction() } From 7c2fa52db7236f676811a69b95100f42c5c1fd97 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Wed, 15 May 2019 12:00:48 +0200 Subject: [PATCH 10/21] add transaction filtering management --- .../net/pokeranalytics/android/model/filter/Query.kt | 12 +++++++++++- .../android/model/filter/QueryCondition.kt | 7 +++++++ .../pokeranalytics/android/model/realm/Session.kt | 2 +- .../android/model/realm/Transaction.kt | 6 +++++- .../ui/view/rowrepresentable/FilterSectionRow.kt | 4 +--- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt index 2b493d0d..bbb8aec4 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt @@ -67,7 +67,17 @@ class Query { } } - return realmQuery + val queryLastGame = this.conditions.filter { + it is QueryCondition.LastGame + }.firstOrNull() + val queryLastSession = this.conditions.filter { + it is QueryCondition.LastSession + }.firstOrNull() + + queryLastGame?.let { + + } + return realmQuery } fun merge(query: Query) : Query { diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt index 63f246b8..b85d736e 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt @@ -473,6 +473,13 @@ sealed class QueryCondition : FilterElementRow { calendar.add(Calendar.HOUR_OF_DAY, -24) return realmQuery.greaterThanOrEqualTo(fieldName, calendar.time.startOfDay()).and().lessThanOrEqualTo(fieldName, calendar.time.endOfDay()) } + is PastDay -> { + val startDate = Date() + val calendar = Calendar.getInstance() + calendar.time = startDate + calendar.add(Calendar.DAY_OF_YEAR, -singleValue) + return realmQuery.greaterThanOrEqualTo(fieldName, calendar.time.startOfDay()).and().lessThanOrEqualTo(fieldName, startDate.endOfDay()) + } is DuringThisWeek -> { val startDate = Date() val calendar = Calendar.getInstance() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 56d5b759..05253c97 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -91,7 +91,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat AnyDayOfWeek::class.java, IsWeekEnd::class.java, IsWeekDay::class.java -> "dayOfWeek" AnyMonthOfYear::class.java -> "month" AnyYear::class.java -> "year" - IsToday::class.java, WasYesterday::class.java, WasTodayAndYesterday::class.java, DuringThisYear::class.java, DuringThisMonth::class.java, DuringThisWeek::class.java -> "startDate" + PastDay::class.java, IsToday::class.java, WasYesterday::class.java, WasTodayAndYesterday::class.java, DuringThisYear::class.java, DuringThisMonth::class.java, DuringThisWeek::class.java -> "startDate" StartedFromTime::class.java -> "startDateHourMinuteComponent" EndedToTime::class.java -> "endDateHourMinuteComponent" Duration::class.java -> "netDuration" diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt index 0ae2ce7d..56296685 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt @@ -37,8 +37,12 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo return when (queryCondition) { QueryCondition.AnyBankroll::class.java -> "bankroll.id" - QueryCondition.AnyTransactionType::class.java -> "type" + QueryCondition.AnyTransactionType::class.java -> "type.id" QueryCondition.StartedFromDate::class.java, QueryCondition.StartedToDate::class.java -> "date" + QueryCondition.AnyDayOfWeek::class.java, QueryCondition.IsWeekEnd::class.java, QueryCondition.IsWeekDay::class.java -> "dayOfWeek" + QueryCondition.AnyMonthOfYear::class.java -> "month" + QueryCondition.AnyYear::class.java -> "year" + QueryCondition.PastDay::class.java, QueryCondition.IsToday::class.java, QueryCondition.WasYesterday::class.java, QueryCondition.WasTodayAndYesterday::class.java, QueryCondition.DuringThisYear::class.java, QueryCondition.DuringThisMonth::class.java, QueryCondition.DuringThisWeek::class.java -> "date" else -> null } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt index 831e4f8a..4895ef45 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt @@ -113,9 +113,7 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable { addAll(QueryCondition.moreOrLess()) addAll(QueryCondition.moreOrLess()) } - TRANSACTION_TYPES -> arrayListOf().apply { - - } + TRANSACTION_TYPES -> Criteria.TransactionTypes.queryConditions.mapFirstCondition() else -> arrayListOf() }.apply { this.forEach { From 03bd21997e976c86390e8432d875a92b1963f01e Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Wed, 15 May 2019 16:25:43 +0200 Subject: [PATCH 11/21] add a localizedName method to query class requiring a context --- .../pokeranalytics/android/model/filter/Query.kt | 15 +++++---------- .../android/model/filter/QueryCondition.kt | 2 +- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt index bbb8aec4..f4e0106e 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt @@ -1,8 +1,7 @@ package net.pokeranalytics.android.model.filter -import android.content.Context import io.realm.RealmQuery -import net.pokeranalytics.android.R +import io.realm.kotlin.where fun List.mapFirstCondition() : List { return this.map { it.conditions.first() } @@ -67,15 +66,11 @@ class Query { } } - val queryLastGame = this.conditions.filter { - it is QueryCondition.LastGame + val queryLast = this.conditions.filter { + it is QueryCondition.Last }.firstOrNull() - val queryLastSession = this.conditions.filter { - it is QueryCondition.LastSession - }.firstOrNull() - - queryLastGame?.let { - + queryLast?.let { + return realmQuery.limit((it as QueryCondition.Last).singleValue.toLong()) } return realmQuery } diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt index b85d736e..5db0d3ad 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt @@ -348,7 +348,7 @@ sealed class QueryCondition : FilterElementRow { } } - open class TournamentFinalPosition(): ListOfInt() { + class TournamentFinalPosition(): ListOfInt() { constructor(operator: Operator, finalPosition: Int) : this() { this.operator = operator this.listOfValues = arrayListOf(finalPosition) From df3ac66b1f2c62a10ca7d94eac0ca5da7844fba9 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Thu, 16 May 2019 14:41:18 +0200 Subject: [PATCH 12/21] merge conflict fix --- .../android/model/filter/Query.kt | 2 + .../android/model/filter/QueryCondition.kt | 95 +++++++++++-------- .../rowrepresentable/FilterCategoryRow.kt | 4 +- .../view/rowrepresentable/FilterSectionRow.kt | 2 +- .../util/extensions/NumbersExtension.kt | 4 +- 5 files changed, 63 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt index f4e0106e..6f5baf3c 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt @@ -1,7 +1,9 @@ package net.pokeranalytics.android.model.filter +import android.content.Context import io.realm.RealmQuery import io.realm.kotlin.where +import net.pokeranalytics.android.R fun List.mapFirstCondition() : List { return this.map { it.conditions.first() } diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt index 5db0d3ad..7a4e5961 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt @@ -80,9 +80,7 @@ sealed class QueryCondition : FilterElementRow { MORE, LESS, EQUALS, - BETWEEN, - BETWEEN_RIGHT_EXCLUSIVE, - BETWEEN_LEFT_EXCLUSIVE, + TRUE, ; } @@ -111,7 +109,7 @@ sealed class QueryCondition : FilterElementRow { } } - open var operator: Operator = Operator.ANY + abstract var operator: Operator abstract class ListOfValues: QueryCondition(), Comparable> where T:Comparable { @@ -138,29 +136,37 @@ sealed class QueryCondition : FilterElementRow { abstract class ListOfDouble: ListOfValues() { open var sign: Int = 1 - + override var operator: Operator = Operator.ANY override var listOfValues = arrayListOf(0.0) override fun updateValueBy(filterCondition: FilterCondition) { super.updateValueBy(filterCondition) listOfValues = filterCondition.getValues() } override fun labelForValue(value: Double, context: Context): String { - return value.toCurrency(UserDefaults.currency) + val prefix = this.resId?.let { + context.getString(it)+" " + } ?: "" + return prefix+value.toCurrency(UserDefaults.currency) } } abstract class ListOfInt: ListOfValues() { + override var operator: Operator = Operator.ANY override var listOfValues = arrayListOf(0) override fun updateValueBy(filterCondition: FilterCondition) { super.updateValueBy(filterCondition) listOfValues = filterCondition.getValues() } override fun labelForValue(value: Int, context: Context): String { - return value.toString() + val prefix = this.resId?.let { + context.getString(it)+" " + } ?: "" + return prefix+value.toString() } } abstract class ListOfString: ListOfValues() { + override var operator: Operator = Operator.ANY override var listOfValues = ArrayList() override fun labelForValue(value: String, context: Context): String { return value } override fun updateValueBy(filterCondition: FilterCondition) { @@ -171,8 +177,12 @@ sealed class QueryCondition : FilterElementRow { abstract class SingleDate: SingleValue() { override fun labelForValue(value: Date, context: Context): String { - return value.toString() + val prefix = this.resId?.let { + context.getString(it)+" " + } ?: "" + return prefix+value.toString() } + override var listOfValues = ArrayList() override var singleValue: Date @@ -190,8 +200,12 @@ sealed class QueryCondition : FilterElementRow { abstract class SingleInt: SingleValue() { override fun labelForValue(value: Int, context: Context): String { - return value.toString() + val prefix = this.resId?.let { + context.getString(it)+" " + } ?: "" + return prefix+value.toString() } + override var singleValue: Int get() { return listOfValues.firstOrNull() ?: 0 } set(value) { @@ -205,7 +219,12 @@ sealed class QueryCondition : FilterElementRow { } } - override fun getDisplayName(context: Context): String { return baseId } + override fun getDisplayName(context: Context): String { + this.resId?.let { + return context.getString(it) + } + return baseId + } override var filterSectionRow: FilterSectionRow = FilterSectionRow.CASH_TOURNAMENT @@ -250,21 +269,17 @@ sealed class QueryCondition : FilterElementRow { override val showTime: Boolean = true } - object IsLive : QueryCondition() { - override fun getDisplayName(context: Context): String { return "Live" } + abstract class TrueQueryCondition: QueryCondition() { + override var operator: Operator = Operator.TRUE } - object IsCash : QueryCondition() { - override fun getDisplayName(context: Context): String { return "Cash" } - } + object IsLive : TrueQueryCondition() - object IsOnline : QueryCondition() { - override fun getDisplayName(context: Context): String { return "Online" } - } + object IsCash : TrueQueryCondition() - object IsTournament : QueryCondition() { - override fun getDisplayName(context: Context): String { return "Tournament" } - } + object IsOnline : TrueQueryCondition() + + object IsTournament : TrueQueryCondition() class AnyBankroll(): QueryDataCondition() { override var entity: Class = Bankroll::class.java @@ -336,8 +351,12 @@ sealed class QueryCondition : FilterElementRow { class AnyBlind: ListOfString() - class LastGame: SingleInt() - class LastSession: SingleInt() + object Last: SingleInt() { + override var operator = Operator.EQUALS + override fun getDisplayName(context: Context): String { + return "${context.getString(R.string.last_i_records)} $singleValue" + } + } class NumberOfTable: ListOfInt() @@ -356,6 +375,7 @@ sealed class QueryCondition : FilterElementRow { } open class NetAmount: ListOfDouble() + class NetAmountWon: NetAmount() class NetAmountLost: NetAmount() { override var sign: Int = -1 } @@ -392,26 +412,31 @@ sealed class QueryCondition : FilterElementRow { } } - object IsWeekDay: QueryCondition() - object IsWeekEnd: QueryCondition() - object IsToday: QueryCondition() - object WasYesterday: QueryCondition() - object WasTodayAndYesterday: QueryCondition() - object DuringThisWeek: QueryCondition() - object DuringThisMonth: QueryCondition() - object DuringThisYear: QueryCondition() + object IsWeekDay: TrueQueryCondition() + object IsWeekEnd: TrueQueryCondition() + object IsToday: TrueQueryCondition() + object WasYesterday: TrueQueryCondition() + object WasTodayAndYesterday: TrueQueryCondition() + object DuringThisWeek: TrueQueryCondition() + object DuringThisMonth: TrueQueryCondition() + object DuringThisYear: TrueQueryCondition() class TournamentFee: ListOfDouble() { override fun labelForValue(value: Double, context: Context): String { - return value.toCurrency(UserDefaults.currency) + val prefix = this.resId?.let { + context.getString(it)+" " + } ?: "" + return prefix+value.toCurrency(UserDefaults.currency) } } class PastDay: SingleInt() { + override var operator = Operator.EQUALS override val viewType: Int = RowViewType.TITLE_VALUE_CHECK.ordinal } class Duration: SingleInt() { + override var operator = Operator.EQUALS var minutes:Int get() { return singleValue } set(value) { listOfValues = arrayListOf(value) } @@ -591,8 +616,6 @@ sealed class QueryCondition : FilterElementRow { get() { return when (this) { is PastDay -> RowViewType.TITLE_VALUE_CHECK.ordinal - is LastGame -> RowViewType.TITLE_VALUE_CHECK.ordinal - is LastSession -> RowViewType.TITLE_VALUE_CHECK.ordinal else -> { when (this.operator) { Operator.MORE -> RowViewType.TITLE_VALUE_CHECK.ordinal @@ -607,8 +630,6 @@ sealed class QueryCondition : FilterElementRow { get() { return when (this) { is PastDay -> BottomSheetType.EDIT_TEXT - is LastGame -> BottomSheetType.EDIT_TEXT - is LastSession -> BottomSheetType.EDIT_TEXT else -> { when (this.operator) { Operator.MORE -> BottomSheetType.EDIT_TEXT @@ -637,8 +658,6 @@ sealed class QueryCondition : FilterElementRow { is IsWeekDay -> R.string.week_days is IsWeekEnd -> R.string.weekend is PastDay -> R.string.period_in_days - is LastGame -> R.string.last_records - is LastSession -> R.string.last_sessions is NetAmountWon -> { when (this.operator) { Operator.MORE -> R.string.won_amount_more_than diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt index cca2e114..72cc0391 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt @@ -16,7 +16,7 @@ enum class FilterCategoryRow(override val resId: Int?, override val viewType: In GENERAL(R.string.general), DATE(R.string.date), TIME_FRAME(R.string.duration), - SESSIONS(R.string.sessions), + //SESSIONS(R.string.sessions), CASH(R.string.cash), TOURNAMENT(R.string.tournament), ONLINE(R.string.online), @@ -92,7 +92,7 @@ enum class FilterCategoryRow(override val resId: Int?, override val viewType: In SESSION_DURATION, TIME_FRAME_RANGE ) - SESSIONS -> arrayListOf(FilterSectionRow.SESSIONS) + //SESSIONS -> arrayListOf(FilterSectionRow.SESSIONS) BANKROLLS -> arrayListOf( BANKROLL ) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt index 4895ef45..06e24bd3 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt @@ -87,7 +87,7 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable { TIME_FRAME_RANGE -> arrayListOf(QueryCondition.StartedFromTime(), QueryCondition.EndedToTime()) // Sessions - SESSIONS -> arrayListOf(QueryCondition.LastGame(), QueryCondition.LastSession()) + //SESSIONS -> arrayListOf(QueryCondition.LastGame(), QueryCondition.LastSession()) // Cash BLIND -> Criteria.Blinds.queryConditions.mapFirstCondition() diff --git a/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt b/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt index 1313248c..39a3f043 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt @@ -38,9 +38,7 @@ fun Double.round(): String { } fun Double.roundOffDecimal(): Double { - val df = DecimalFormat("#.##") - df.roundingMode = RoundingMode.CEILING - return df.format(this).toDouble() + return this.toBigDecimal().setScale(2, RoundingMode.CEILING).toDouble() } fun Double.formatted(): String { From fd2fa40e2071a1c722598353cea86903204517b2 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Thu, 16 May 2019 16:00:24 +0200 Subject: [PATCH 13/21] fix issues with filter titles --- .../android/model/filter/QueryCondition.kt | 47 ++++++++++++++++--- .../android/model/realm/Session.kt | 2 +- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt index 7a4e5961..650ef278 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt @@ -20,10 +20,7 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.UserDefaults -import net.pokeranalytics.android.util.extensions.endOfDay -import net.pokeranalytics.android.util.extensions.hourMinute -import net.pokeranalytics.android.util.extensions.startOfDay -import net.pokeranalytics.android.util.extensions.toCurrency +import net.pokeranalytics.android.util.extensions.* import java.text.DateFormatSymbols import java.util.* import kotlin.collections.ArrayList @@ -180,7 +177,7 @@ sealed class QueryCondition : FilterElementRow { val prefix = this.resId?.let { context.getString(it)+" " } ?: "" - return prefix+value.toString() + return prefix+value.shortDate() } override var listOfValues = ArrayList() @@ -354,17 +351,32 @@ sealed class QueryCondition : FilterElementRow { object Last: SingleInt() { override var operator = Operator.EQUALS override fun getDisplayName(context: Context): String { + //TODO update string "last %i" return "${context.getString(R.string.last_i_records)} $singleValue" } } - class NumberOfTable: ListOfInt() + class NumberOfTable: ListOfInt() { + override fun labelForValue(value: Int, context: Context): String { + val prefix = this.resId?.let { + context.getString(it) + " " + } ?: "" + return prefix + value.toString() + " " + context.getString(R.string.tables) + } + } class NumberOfRebuy(): ListOfDouble() { constructor(operator: Operator, numberOfRebuy: Double) : this() { this.operator = operator this.listOfValues = arrayListOf(numberOfRebuy) } + + override fun labelForValue(value: Double, context: Context): String { + val prefix = this.resId?.let { + context.getString(it) + " " + } ?: "" + return prefix + value.toString() + } } class TournamentFinalPosition(): ListOfInt() { @@ -372,6 +384,13 @@ sealed class QueryCondition : FilterElementRow { this.operator = operator this.listOfValues = arrayListOf(finalPosition) } + + override fun labelForValue(value: Int, context: Context): String { + val prefix = this.resId?.let { + context.getString(it) + " " + } ?: "" + return prefix + value.toString() + } } open class NetAmount: ListOfDouble() @@ -379,7 +398,14 @@ sealed class QueryCondition : FilterElementRow { class NetAmountWon: NetAmount() class NetAmountLost: NetAmount() { override var sign: Int = -1 } - class TournamentNumberOfPlayer: ListOfInt() + class TournamentNumberOfPlayer: ListOfInt() { + override fun labelForValue(value: Int, context: Context): String { + val prefix = this.resId?.let { + context.getString(it) + " " + } ?: "" + return prefix + value.toString() + context.getString(R.string.number_of_players) + } + } class StartedFromDate: DateQuery() { override var operator = Operator.MORE } class StartedToDate: DateQuery() { override var operator = Operator.LESS } @@ -433,6 +459,13 @@ sealed class QueryCondition : FilterElementRow { class PastDay: SingleInt() { override var operator = Operator.EQUALS override val viewType: Int = RowViewType.TITLE_VALUE_CHECK.ordinal + + override fun labelForValue(value: Int, context: Context): String { + val suffix = this.resId?.let { + " "+context.getString(it) + } ?: "" + return value.toString() + suffix + } } class Duration: SingleInt() { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 05253c97..33123a35 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -80,7 +80,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat AnyTableSize::class.java -> "tableSize" AnyTournamentType::class.java -> "tournamentType" AnyBlind::class.java -> "blinds" - NumberOfTable::class.java -> "numberOfTable" + NumberOfTable::class.java -> "numberOfTables" NetAmountWon::class.java, NetAmountLost::class.java -> "computableResults.ratedNet" NumberOfRebuy::class.java -> "result.numberOfRebuy" TournamentNumberOfPlayer::class.java -> "result.tournamentNumberOfPlayers" From 386a5bab377f1136707f4f1e249abc72bbb0b091 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 17:07:20 +0200 Subject: [PATCH 14/21] Clean and improve models & migration --- .../migrations/PokerAnalyticsMigration.kt | 9 +++-- .../android/model/realm/CustomField.kt | 39 ++++++++++++++++++- .../android/model/realm/CustomFieldEntry.kt | 25 +++++++++++- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index a97162e2..649f06a0 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -2,6 +2,7 @@ package net.pokeranalytics.android.model.migrations import io.realm.DynamicRealm import io.realm.RealmMigration +import net.pokeranalytics.android.model.realm.CustomField import net.pokeranalytics.android.model.realm.CustomFieldEntry import timber.log.Timber @@ -104,8 +105,9 @@ class PokerAnalyticsMigration : RealmMigration { } schema.create("CustomFieldEntry")?.let { it.addField("id", String::class.java).setRequired("id", true) - it.addField("value", String::class.java).setNullable("type", false) - it.addField("order", Integer::class.java).setNullable("type", false) + it.addField("value", String::class.java).setNullable("value", false) + it.addField("order", Integer::class.java).setNullable("order", false) + it.addField("customField", CustomField::class.java).setNullable("customField", false) } schema.get("CustomField")?.let { it.addField("type", Integer::class.java).setNullable("type", false) @@ -113,7 +115,6 @@ class PokerAnalyticsMigration : RealmMigration { it.addField("sortCondition", Integer::class.java) it.addRealmListField("entries", CustomFieldEntry::class.java) } - schema.get("ReportSetup")?.let { it.addRealmListField("statIds", Int::class.java) it.addRealmListField("criteriaIds", Int::class.java) @@ -122,10 +123,10 @@ class PokerAnalyticsMigration : RealmMigration { it.addRealmObjectField("filter", filterSchema) } } - schema.get("Session")?.let { it.addField("startDateHourMinuteComponent", Double::class.java).setNullable("startDateHourMinuteComponent", true) it.addField("endDateHourMinuteComponent", Double::class.java).setNullable("endDateHourMinuteComponent", true) + it.addRealmListField("customFieldEntries", CustomFieldEntry::class.java) } currentVersion++ } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt index a1876108..7620e2e2 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt @@ -1,6 +1,7 @@ package net.pokeranalytics.android.model.realm import android.content.Context +import android.text.InputType import io.realm.Realm import io.realm.RealmList import io.realm.RealmObject @@ -11,6 +12,7 @@ import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus 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.fragment.components.bottomsheet.BottomSheetType import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.RowViewType @@ -58,13 +60,16 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa updateRowRepresentation() } + override fun localizedTitle(context: Context): String { + return this.name + } override fun getDisplayName(context: Context): String { return this.name } @Ignore - override val viewType: Int = RowViewType.TITLE_VALUE_ARROW.ordinal + override var viewType: Int = RowViewType.TITLE_VALUE_ARROW.ordinal @Ignore private var rowRepresentation: List = mutableListOf() @@ -105,6 +110,14 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa return R.string.relationship_error } + override val bottomSheetType: BottomSheetType + get() { + return when (type) { + Type.LIST.uniqueIdentifier -> BottomSheetType.LIST_STATIC + else -> BottomSheetType.EDIT_TEXT + } + } + override fun editDescriptors(row: RowRepresentable): ArrayList? { return when (row) { is CustomFieldEntry -> row.editingDescriptors( @@ -116,6 +129,28 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa } } + override fun editingDescriptors(map: Map): ArrayList? { + return when (type) { + Type.LIST.uniqueIdentifier -> { + val defaultValue: Any? by map + val data: RealmList? by map + arrayListOf( + RowRepresentableEditDescriptor(defaultValue, staticData = data) + ) + } + else -> { + val defaultValue: String? by map + arrayListOf( + RowRepresentableEditDescriptor( + defaultValue, inputType = InputType.TYPE_CLASS_NUMBER + or InputType.TYPE_NUMBER_FLAG_DECIMAL + or InputType.TYPE_NUMBER_FLAG_SIGNED + ) + ) + } + } + } + /** * Update the row representation */ @@ -160,6 +195,7 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa */ fun addEntry(): CustomFieldEntry { val entry = CustomFieldEntry() + entry.customField = this entries.add(entry) sortEntries() updateRowRepresentation() @@ -175,5 +211,4 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa updateRowRepresentation() } - } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt index 6c17e556..314f2002 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt @@ -11,15 +11,20 @@ import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.util.NULL_TEXT +import net.pokeranalytics.android.util.extensions.toCurrency import java.util.* +import java.util.Currency open class CustomFieldEntry : RealmObject(), RowRepresentable { @PrimaryKey var id = UUID.randomUUID().toString() - var value: String = "" var order: Int = 0 + var customField: CustomField? = null + + var value: String = "" + @Ignore var isMovable: Boolean = false @@ -55,4 +60,22 @@ open class CustomFieldEntry : RealmObject(), RowRepresentable { ) } + /** + * Return the amount + */ + fun getFormattedValue(currency: Currency? = null): String { + return when (customField?.type) { + CustomField.Type.AMOUNT.uniqueIdentifier -> { + try { + value.toDouble().toCurrency(currency) + } catch (e: Exception) { + NULL_TEXT + } + } + else -> { + value + } + } + } + } \ No newline at end of file From 2554eddb62d929118628473555da2399bc49c55d Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 17:07:29 +0200 Subject: [PATCH 15/21] Add custom fields for Session --- .../android/model/realm/Session.kt | 219 ++++++++++++------ .../components/DeletableItemFragment.kt | 13 +- .../BottomSheetStaticListFragment.kt | 3 +- 3 files changed, 155 insertions(+), 80 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 56d5b759..b1644a88 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -39,6 +39,7 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.UserDefaults import net.pokeranalytics.android.util.extensions.* +import timber.log.Timber import java.text.DateFormat import java.util.* import java.util.Currency @@ -67,34 +68,34 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat return realm.copyToRealm(session) } - fun fieldNameForQueryType(queryCondition: Class < out QueryCondition >): String? { - return when (queryCondition) { + fun fieldNameForQueryType(queryCondition: Class): String? { + return when (queryCondition) { IsLive::class.java, IsOnline::class.java -> "bankroll.live" IsCash::class.java, IsTournament::class.java -> "type" AnyBankroll::class.java -> "bankroll.id" - AnyGame::class.java -> "game.id" - AnyTournamentName::class.java -> "tournamentName.id" - AnyTournamentFeature::class.java, AllTournamentFeature::class.java -> "tournamentFeatures.id" - AnyLocation::class.java -> "location.id" - AnyLimit::class.java -> "limit" - AnyTableSize::class.java -> "tableSize" - AnyTournamentType::class.java -> "tournamentType" - AnyBlind::class.java -> "blinds" - NumberOfTable::class.java -> "numberOfTable" - NetAmountWon::class.java, NetAmountLost::class.java -> "computableResults.ratedNet" - NumberOfRebuy::class.java -> "result.numberOfRebuy" - TournamentNumberOfPlayer::class.java -> "result.tournamentNumberOfPlayers" - TournamentFinalPosition::class.java -> "result.tournamentFinalPosition" - TournamentFee::class.java -> "tournamentEntryFee" - StartedFromDate::class.java, StartedToDate::class.java -> "startDate" - EndedFromDate::class.java, EndedToDate::class.java -> "endDate" - AnyDayOfWeek::class.java, IsWeekEnd::class.java, IsWeekDay::class.java -> "dayOfWeek" - AnyMonthOfYear::class.java -> "month" - AnyYear::class.java -> "year" + AnyGame::class.java -> "game.id" + AnyTournamentName::class.java -> "tournamentName.id" + AnyTournamentFeature::class.java, AllTournamentFeature::class.java -> "tournamentFeatures.id" + AnyLocation::class.java -> "location.id" + AnyLimit::class.java -> "limit" + AnyTableSize::class.java -> "tableSize" + AnyTournamentType::class.java -> "tournamentType" + AnyBlind::class.java -> "blinds" + NumberOfTable::class.java -> "numberOfTable" + NetAmountWon::class.java, NetAmountLost::class.java -> "computableResults.ratedNet" + NumberOfRebuy::class.java -> "result.numberOfRebuy" + TournamentNumberOfPlayer::class.java -> "result.tournamentNumberOfPlayers" + TournamentFinalPosition::class.java -> "result.tournamentFinalPosition" + TournamentFee::class.java -> "tournamentEntryFee" + StartedFromDate::class.java, StartedToDate::class.java -> "startDate" + EndedFromDate::class.java, EndedToDate::class.java -> "endDate" + AnyDayOfWeek::class.java, IsWeekEnd::class.java, IsWeekDay::class.java -> "dayOfWeek" + AnyMonthOfYear::class.java -> "month" + AnyYear::class.java -> "year" IsToday::class.java, WasYesterday::class.java, WasTodayAndYesterday::class.java, DuringThisYear::class.java, DuringThisMonth::class.java, DuringThisWeek::class.java -> "startDate" - StartedFromTime::class.java -> "startDateHourMinuteComponent" - EndedToTime::class.java -> "endDateHourMinuteComponent" - Duration::class.java -> "netDuration" + StartedFromTime::class.java -> "startDateHourMinuteComponent" + EndedToTime::class.java -> "endDateHourMinuteComponent" + Duration::class.java -> "netDuration" else -> null } } @@ -125,25 +126,25 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat override var year: Int? = null override var dayOfMonth: Int? = null - private var startDateHourMinuteComponent: Double? = null - get() { - if (field == null && startDate != null) { - val cal = Calendar.getInstance() - cal.time = startDate - field = cal.hourMinute() - } - return field - } - - private var endDateHourMinuteComponent: Double? = null - get() { - if (field == null && endDate != null) { - val cal = Calendar.getInstance() - cal.time = endDate - field = cal.hourMinute() - } - return field - } + private var startDateHourMinuteComponent: Double? = null + get() { + if (field == null && startDate != null) { + val cal = Calendar.getInstance() + cal.time = startDate + field = cal.hourMinute() + } + return field + } + + private var endDateHourMinuteComponent: Double? = null + get() { + if (field == null && endDate != null) { + val cal = Calendar.getInstance() + cal.time = endDate + field = cal.hourMinute() + } + return field + } /** * The start date of the session @@ -151,13 +152,13 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat var startDate: Date? = null set(value) { field = value - if (field == null) { - startDateHourMinuteComponent = null - } else { - val cal = Calendar.getInstance() - cal.time = field - startDateHourMinuteComponent = cal.hourMinute() - } + if (field == null) { + startDateHourMinuteComponent = null + } else { + val cal = Calendar.getInstance() + cal.time = field + startDateHourMinuteComponent = cal.hourMinute() + } this.updateTimeParameter(field) this.computeNetDuration() @@ -176,15 +177,15 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat var endDate: Date? = null set(value) { field = value - if (field == null) { - endDateHourMinuteComponent = null - } else { - val cal = Calendar.getInstance() - cal.time = field - endDateHourMinuteComponent = cal.hourMinute() - } - - this.computeNetDuration() + if (field == null) { + endDateHourMinuteComponent = null + } else { + val cal = Calendar.getInstance() + cal.time = field + endDateHourMinuteComponent = cal.hourMinute() + } + + this.computeNetDuration() this.dateChanged() this.defineDefaultTournamentBuyinIfNecessary() this.computeStats() @@ -266,7 +267,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat field = value this.computeStats() formatBlinds() - this.result?.computeNumberOfRebuy() + this.result?.computeNumberOfRebuy() } var blinds: String? = null @@ -276,10 +277,10 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat // The entry fee of the tournament var tournamentEntryFee: Double? = null - set(value) { - field = value - this.result?.computeNumberOfRebuy() - } + set(value) { + field = value + this.result?.computeNumberOfRebuy() + } // The total number of players who participated in the tournament var tournamentNumberOfPlayers: Int? = null @@ -293,6 +294,9 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat // The features of the tournament, like Knockout, Shootout, Turbo... var tournamentFeatures: RealmList = RealmList() + // The custom fields values + var customFieldEntries: RealmList = RealmList() + fun bankrollHasBeenUpdated() { formatBlinds() } @@ -574,7 +578,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat return blinds ?: NULL_TEXT } - fun formatBlinds() { + fun formatBlinds() { blinds = null if (cgBigBlind == null) return cgBigBlind?.let { bb -> @@ -589,9 +593,11 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat * Delete the object from realm */ fun delete() { - realm.executeTransaction { - cleanup() - deleteFromRealm() + if (isValid) { + realm.executeTransaction { + cleanup() + deleteFromRealm() + } } } @@ -613,6 +619,16 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat @Ignore override val viewType: Int = RowViewType.ROW_SESSION.ordinal + // Override to surcharge custom field viewType + override fun viewTypeForPosition(position: Int): Int { + rowRepresentationForCurrentState[position].let { + if (it is CustomField) { + return RowViewType.TITLE_VALUE.ordinal + } + } + return super.viewTypeForPosition(position) + } + override fun getDisplayName(context: Context): String { return "Session ${this.creationDate}" } @@ -678,6 +694,13 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat // Rows rows.addAll(SessionRow.getRows(this)) + + // Add custom fields + realm?.let { + rows.add(SeparatorRow()) + rows.addAll(LiveData.CUSTOM_FIELD.itemsArray(it) as ArrayList) + } + return rows } @@ -711,10 +734,12 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat SessionRow.START_DATE -> this.startDate?.shortDateTime() ?: NULL_TEXT SessionRow.TABLE_SIZE -> this.tableSize?.let { TableSize(it).localizedTitle(context) } ?: NULL_TEXT SessionRow.TIPS -> result?.tips?.toCurrency(currency) ?: NULL_TEXT - SessionRow.TOURNAMENT_TYPE -> this.tournamentType?.let { - TournamentType.values()[it].localizedTitle(context) - } ?: run { - NULL_TEXT + SessionRow.TOURNAMENT_TYPE -> { + this.tournamentType?.let { + TournamentType.values()[it].localizedTitle(context) + } ?: run { + NULL_TEXT + } } SessionRow.TOURNAMENT_FEATURE -> { if (tournamentFeatures.size > 2) { @@ -730,6 +755,12 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } } SessionRow.TOURNAMENT_NAME -> tournamentName?.name ?: NULL_TEXT + is CustomField -> { + customFieldEntries.find { it.customField?.id == row.id }?.let { customFieldEntry -> + return customFieldEntry.getFormattedValue(currency) + } + return NULL_TEXT + } else -> throw UnmanagedRowRepresentableException("Unmanaged row = ${row}") } } @@ -837,6 +868,19 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat "tips" to result?.tips ) ) + is CustomField -> { + row.editingDescriptors( + when (row.type) { + CustomField.Type.LIST.uniqueIdentifier -> mapOf( + "defaultValue" to customFieldEntries.find { it.customField?.id == row.id }?.value, + "data" to row.entries + ) + else -> mapOf( + "defaultValue" to customFieldEntries.find { it.customField?.id == row.id }?.value + ) + } + ) + } else -> null } } @@ -946,7 +990,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat result = localResult } SessionRow.TOURNAMENT_NAME -> tournamentName = value as TournamentName? - SessionRow.TOURNAMENT_TYPE -> tournamentType = value as Int? + SessionRow.TOURNAMENT_TYPE -> tournamentType = (value as TournamentType?)?.ordinal SessionRow.TOURNAMENT_FEATURE -> { value?.let { @@ -956,6 +1000,33 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat tournamentFeatures.removeAll(this.tournamentFeatures) } } + + is CustomField -> { + customFieldEntries.filter { it.customField?.id == row.id }.let { + customFieldEntries.removeAll(it) + } + when (row.type) { + CustomField.Type.AMOUNT.uniqueIdentifier, + CustomField.Type.NUMBER.uniqueIdentifier -> { + Timber.d("AMOUNT or NUMBER: ${value}") + if (value != null) { + val customFieldEntry = CustomFieldEntry() + customFieldEntry.customField = row + customFieldEntry.value = value.toString() + Timber.d("customFieldEntry: ${customFieldEntry.id}") + Timber.d("customFieldEntry: ${customFieldEntry.customField}") + Timber.d("customFieldEntry: ${customFieldEntry.value}") + customFieldEntries.add(customFieldEntry) + } + Timber.d("customFieldEntries: ${customFieldEntries.size}") + } + CustomField.Type.LIST.uniqueIdentifier -> { + if (value != null && value is CustomFieldEntry) { + customFieldEntries.add(value) + } + } + } + } } } @@ -1013,7 +1084,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat style: GraphFragment.Style, groupName: String, context: Context - ) : LegendContent { + ): LegendContent { when (style) { GraphFragment.Style.MULTILINE -> { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt index f824b3d1..29c89ad5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt @@ -18,6 +18,7 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter open class DeletableItemFragment : RealmFragment() { private var deletedItem: RealmObject? = null + private var itemHasBeenReInserted: Boolean = false private var lastDeletedItemPosition: Int = 0 private var dataListAdapter: RowRepresentableAdapter? = null private var coordinatorLayout: CoordinatorLayout? = null @@ -63,6 +64,7 @@ open class DeletableItemFragment : RealmFragment() { getRealm().executeTransaction { itemToDelete.deleteFromRealm() } + itemHasBeenReInserted = false updateUIAfterDeletion(itemPosition) showUndoSnackBar() } else { @@ -85,10 +87,13 @@ open class DeletableItemFragment : RealmFragment() { this.coordinatorLayout?.let { view -> snackBar = Snackbar.make(view, message, Snackbar.LENGTH_INDEFINITE) snackBar?.setAction(R.string.cancel) { - getRealm().executeTransaction { realm -> - deletedItem?.let { - val item = realm.copyToRealmOrUpdate(it) - updateUIAfterUndoDeletion(item) + if (!itemHasBeenReInserted) { + itemHasBeenReInserted = true + getRealm().executeTransaction { realm -> + deletedItem?.let { + val item = realm.copyToRealmOrUpdate(it) + updateUIAfterUndoDeletion(item) + } } } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetStaticListFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetStaticListFragment.kt index a60f51f0..7af3f1da 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetStaticListFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetStaticListFragment.kt @@ -8,7 +8,6 @@ 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.exceptions.RowRepresentableEditDescriptorException -import net.pokeranalytics.android.model.TournamentType import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource @@ -36,7 +35,7 @@ class BottomSheetStaticListFragment : BottomSheetFragment(), StaticRowRepresenta } override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { - this.delegate.onRowValueChanged((row as TournamentType).ordinal, this.row) + this.delegate.onRowValueChanged(row, this.row) dismiss() super.onRowSelected(position, row, fromAction) } From 47de41044d8f37ab9cbe108d9be29f4ba4bbe460 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 18:44:56 +0200 Subject: [PATCH 16/21] Refactor icon names --- ...eline_all_inclusive_24px.xml => ic_baseline_all_inclusive.xml} | 0 .../{ic_baseline_email_24px.xml => ic_baseline_email.xml} | 0 .../{ic_baseline_vpn_key_24px.xml => ic_baseline_vpn_key.xml} | 0 .../{ic_baseline_wifi_off_24px.xml => ic_baseline_wifi_off.xml} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename app/src/main/res/drawable/{ic_baseline_all_inclusive_24px.xml => ic_baseline_all_inclusive.xml} (100%) rename app/src/main/res/drawable/{ic_baseline_email_24px.xml => ic_baseline_email.xml} (100%) rename app/src/main/res/drawable/{ic_baseline_vpn_key_24px.xml => ic_baseline_vpn_key.xml} (100%) rename app/src/main/res/drawable/{ic_baseline_wifi_off_24px.xml => ic_baseline_wifi_off.xml} (100%) diff --git a/app/src/main/res/drawable/ic_baseline_all_inclusive_24px.xml b/app/src/main/res/drawable/ic_baseline_all_inclusive.xml similarity index 100% rename from app/src/main/res/drawable/ic_baseline_all_inclusive_24px.xml rename to app/src/main/res/drawable/ic_baseline_all_inclusive.xml diff --git a/app/src/main/res/drawable/ic_baseline_email_24px.xml b/app/src/main/res/drawable/ic_baseline_email.xml similarity index 100% rename from app/src/main/res/drawable/ic_baseline_email_24px.xml rename to app/src/main/res/drawable/ic_baseline_email.xml diff --git a/app/src/main/res/drawable/ic_baseline_vpn_key_24px.xml b/app/src/main/res/drawable/ic_baseline_vpn_key.xml similarity index 100% rename from app/src/main/res/drawable/ic_baseline_vpn_key_24px.xml rename to app/src/main/res/drawable/ic_baseline_vpn_key.xml diff --git a/app/src/main/res/drawable/ic_baseline_wifi_off_24px.xml b/app/src/main/res/drawable/ic_baseline_wifi_off.xml similarity index 100% rename from app/src/main/res/drawable/ic_baseline_wifi_off_24px.xml rename to app/src/main/res/drawable/ic_baseline_wifi_off.xml From 48a0e1083f70d97e0a10f1b97f24ad6bfa440bdf Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 18:45:02 +0200 Subject: [PATCH 17/21] Improve subscription UI --- .../ui/fragment/SubscriptionFragment.kt | 58 +++++++++---- .../components/ScreenSlidePageFragment.kt | 9 ++ .../res/layout/fragment_screen_slide_page.xml | 85 ++++++++++--------- .../main/res/layout/fragment_subscription.xml | 23 +++-- 4 files changed, 109 insertions(+), 66 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt index 68c702c0..3f26b19d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt @@ -31,10 +31,16 @@ import net.pokeranalytics.android.util.Preferences import net.pokeranalytics.android.util.billing.AppGuard import net.pokeranalytics.android.util.billing.IAPProducts import net.pokeranalytics.android.util.billing.PurchaseDelegate +import java.lang.ref.WeakReference import java.time.Period class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListener, PurchaseDelegate, ViewPager.OnPageChangeListener { + companion object { + val parallax: Float = 64f.px + } + + private var pagerAdapter: ScreenSlidePagerAdapter? = null private var selectedProduct: SkuDetails? = null override fun onCreate(savedInstanceState: Bundle?) { @@ -85,7 +91,7 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene // Pager // The pager adapter, which provides the pages to the view pager widget. - val pagerAdapter = ScreenSlidePagerAdapter(requireFragmentManager()) + this.pagerAdapter = ScreenSlidePagerAdapter(requireFragmentManager()) this.pager.adapter = pagerAdapter this.pager.addOnPageChangeListener(this) @@ -108,7 +114,7 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene this.pageIndicator.addView(view, layoutParam) } - this.changeColorOfIndicator(0) + this.updatePagerIndicators(0) } @@ -118,13 +124,21 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene */ private inner class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { + private var fragments: HashMap> = HashMap() + private inner class FeatureDescriptor(var iconResId: Int, var titleResId: Int, var descResId: Int) + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val fragment = super.instantiateItem(container, position) as ScreenSlidePageFragment + fragments[position] = WeakReference(fragment) + return super.instantiateItem(container, position) + } + private val dataSource: List = listOf( - FeatureDescriptor(R.drawable.ic_baseline_all_inclusive_24px, R.string.f_unlimited, R.string.f_unlimited_desc), - FeatureDescriptor(R.drawable.ic_baseline_wifi_off_24px, R.string.f_offline, R.string.f_offline_desc), - FeatureDescriptor(R.drawable.ic_baseline_vpn_key_24px, R.string.f_privacy, R.string.f_privacy_desc), - FeatureDescriptor(R.drawable.ic_baseline_email_24px, R.string.f_support, R.string.f_support_desc) + FeatureDescriptor(R.drawable.ic_baseline_all_inclusive, R.string.f_unlimited, R.string.f_unlimited_desc), + FeatureDescriptor(R.drawable.ic_baseline_wifi_off, R.string.f_offline, R.string.f_offline_desc), + FeatureDescriptor(R.drawable.ic_baseline_vpn_key, R.string.f_privacy, R.string.f_privacy_desc), + FeatureDescriptor(R.drawable.ic_baseline_email, R.string.f_support, R.string.f_support_desc) ) override fun getCount(): Int = this.dataSource.size @@ -133,21 +147,27 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene return ScreenSlidePageFragment(d.iconResId, d.titleResId, d.descResId) } + /** + * Return the fragment at [position] + */ + fun getFragment(position: Int): ScreenSlidePageFragment? { + if (fragments.contains(position)) { + return fragments[position]?.get() + } + return null + } } // SkuDetailsResponseListener override fun onSkuDetailsResponse(responseCode: Int, skuDetailsList: MutableList?) { - if (responseCode == BillingClient.BillingResponse.OK && skuDetailsList != null) { this.hideLoader() selectedProduct = skuDetailsList.first { it.sku == IAPProducts.PRO.identifier } updateUI() } - } private fun updateUI() { - this.selectedProduct?.let { this.purchase.isEnabled = true val perYearString = requireContext().getString(R.string.year_subscription) @@ -162,9 +182,7 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene val formattedFreeTrial = "$freeTrialDays " + requireContext().getString(R.string.days) + " " + requireContext().getString(R.string.free_trial) this.freetrial.text = formattedFreeTrial - } - } // PurchaseDelegate @@ -182,22 +200,30 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene override fun onPageScrollStateChanged(state: Int) {} - override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} + override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { + pagerAdapter?.getFragment(position)?.let { + it.updateViewsPosition(-positionOffset * parallax) + } + pagerAdapter?.getFragment(position + 1)?.let { + it.updateViewsPosition((1 - positionOffset) * parallax) + } + } override fun onPageSelected(position: Int) { - this.changeColorOfIndicator(position) + updatePagerIndicators(position) } - private fun changeColorOfIndicator(position: Int) { + private fun updatePagerIndicators(position: Int) { this.pageIndicator.children.forEachIndexed { index, view -> val drawable = view.background when (drawable) { is GradientDrawable -> { val color = if (position == index) R.color.white else R.color.quantum_grey drawable.setColor(requireContext().getColor(color)) - } else -> {} + } + else -> { + } } - } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/ScreenSlidePageFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/ScreenSlidePageFragment.kt index 326c6a05..534fed12 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/ScreenSlidePageFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/ScreenSlidePageFragment.kt @@ -22,6 +22,15 @@ class ScreenSlidePageFragment(var iconResId: Int, var titleResId: Int, var descr this.icon.setImageResource(this.iconResId) this.title.text = requireContext().getString(this.titleResId) this.description.text = requireContext().getString(this.descriptionResId) + } + + /** + * Update views position + */ + fun updateViewsPosition(position: Float) { + view?.findViewById(R.id.title)?.translationX = position + view?.findViewById(R.id.icon)?.translationX = position + view?.findViewById(R.id.description)?.translationX = position * 2f } diff --git a/app/src/main/res/layout/fragment_screen_slide_page.xml b/app/src/main/res/layout/fragment_screen_slide_page.xml index d0aec965..569f77bc 100644 --- a/app/src/main/res/layout/fragment_screen_slide_page.xml +++ b/app/src/main/res/layout/fragment_screen_slide_page.xml @@ -1,50 +1,53 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/content" + android:layout_width="match_parent" + android:layout_height="match_parent"> - + - + - + - + - + diff --git a/app/src/main/res/layout/fragment_subscription.xml b/app/src/main/res/layout/fragment_subscription.xml index 3603c7b5..587cb8e5 100644 --- a/app/src/main/res/layout/fragment_subscription.xml +++ b/app/src/main/res/layout/fragment_subscription.xml @@ -39,23 +39,28 @@ + app:layout_constraintHeight_percent="0.6" + app:layout_constraintVertical_bias="0.4" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/freetrial" /> + app:layout_constraintTop_toBottomOf="@id/pager" /> Date: Thu, 16 May 2019 18:54:21 +0200 Subject: [PATCH 18/21] Add save validation --- .../pokeranalytics/android/model/realm/CustomField.kt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt index 7620e2e2..5942f8e6 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt @@ -87,20 +87,21 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa } override fun isValidForSave(): Boolean { - return true - } - - override fun alreadyExists(realm: Realm): Boolean { - return realm.where(this::class.java).equalTo("name", this.name).and().notEqualTo("id", this.id).findAll().isNotEmpty() + return super.isValidForSave() } override fun getFailedSaveMessage(status: SaveValidityStatus): Int { return when (status) { SaveValidityStatus.DATA_INVALID -> R.string.cf_empty_field_error + SaveValidityStatus.ALREADY_EXISTS -> R.string.duplicate_cf_error else -> super.getFailedSaveMessage(status) } } + override fun alreadyExists(realm: Realm): Boolean { + return realm.where(this::class.java).equalTo("name", this.name).and().notEqualTo("id", this.id).findAll().isNotEmpty() + } + override fun isValidForDelete(realm: Realm): Boolean { return true } From d00ecdd28c42dff390d3e8974b75cdaf5126b54b Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 18:57:52 +0200 Subject: [PATCH 19/21] Open keyboard when creating custom field --- .../android/ui/fragment/data/CustomFieldDataFragment.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt index 07401dde..c5d18e73 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt @@ -22,7 +22,6 @@ import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.rowrepresentable.CustomFieldRow import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow import net.pokeranalytics.android.util.NULL_TEXT -import timber.log.Timber import java.util.* import kotlin.collections.ArrayList @@ -105,7 +104,6 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - //shouldOpenKeyboard = false initUI() } @@ -157,7 +155,6 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa } override fun onRowValueChanged(value: Any?, row: RowRepresentable) { - Timber.d("onRowValueChanged: $row => $value") when (row) { is CustomFieldEntry -> { row.value = value as String? ?: "" @@ -236,6 +233,11 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa updateUI() rowRepresentableAdapter.notifyDataSetChanged() + if (!isUpdating) { + rowRepresentableForPosition(0)?.let { + onRowSelected(0, it) + } + } } /** From 813186b0238d291ab8cbe5ee7dd35e6c3e02f018 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Thu, 16 May 2019 19:01:04 +0200 Subject: [PATCH 20/21] Add title only when we have items --- .../java/net/pokeranalytics/android/model/realm/CustomField.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt index 5942f8e6..d9faa987 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt @@ -161,8 +161,8 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa rows.add(CustomFieldRow.TYPE) if (type == Type.LIST.ordinal && entries.size >= 0) { - rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, R.string.items_list)) if (entries.isNotEmpty()) { + rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, R.string.items_list)) sortEntries() entries.forEach { customFieldEntry -> customFieldEntry.isMovable = sortCondition == Sort.DEFAULT.uniqueIdentifier From 13e6fed951e2f30c5916fe3c3a36e952ee2a10f7 Mon Sep 17 00:00:00 2001 From: Aurelien Hubert Date: Fri, 17 May 2019 10:37:14 +0200 Subject: [PATCH 21/21] Add clean deletion for CustomField --- .../android/model/interfaces/Manageable.kt | 5 ++ .../android/model/realm/CustomField.kt | 38 ++++++++++++--- .../android/model/realm/CustomFieldEntry.kt | 44 ++++++++++++++++- .../android/ui/extensions/UIExtensions.kt | 24 ++++++---- .../components/DeletableItemFragment.kt | 1 + .../fragment/data/CustomFieldDataFragment.kt | 47 ++++++++++++++++--- .../ui/fragment/data/EditableDataFragment.kt | 4 +- 7 files changed, 140 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt index 3841e81c..7dc3068b 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt @@ -121,4 +121,9 @@ interface Deletable : Identifiable { */ fun getFailedDeleteMessage(status: DeleteValidityStatus): Int + /** + * A method to override if we need to delete linked objects or other stuff + */ + fun deleteDependencies() {} + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt index d9faa987..8afcef6e 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt @@ -7,6 +7,7 @@ import io.realm.RealmList import io.realm.RealmObject import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey +import io.realm.kotlin.where import net.pokeranalytics.android.R import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus import net.pokeranalytics.android.model.interfaces.NameManageable @@ -60,13 +61,9 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa updateRowRepresentation() } - override fun localizedTitle(context: Context): String { - return this.name - } - override fun getDisplayName(context: Context): String { - return this.name - } + @Ignore + private var entriesToDelete: ArrayList = ArrayList() @Ignore override var viewType: Int = RowViewType.TITLE_VALUE_ARROW.ordinal @@ -74,6 +71,15 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa @Ignore private var rowRepresentation: List = mutableListOf() + + override fun localizedTitle(context: Context): String { + return this.name + } + + override fun getDisplayName(context: Context): String { + return this.name + } + override fun adapterRows(): List? { return rowRepresentation } @@ -119,6 +125,13 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa } } + override fun deleteDependencies() { + if (isValid) { + val entries = realm.where().equalTo("customField.id", id).findAll() + entries.deleteAllFromRealm() + } + } + override fun editDescriptors(row: RowRepresentable): ArrayList? { return when (row) { is CustomFieldEntry -> row.editingDescriptors( @@ -208,8 +221,21 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa */ fun deleteEntry(entry: CustomFieldEntry) { entries.remove(entry) + entriesToDelete.add(entry) sortEntries() updateRowRepresentation() } + /** + * Remove the deleted entries from realm + */ + fun cleanDeletedEntries(realm: Realm) { + realm.executeTransaction { + entriesToDelete.forEach { + realm.where().equalTo("id", it.id).findFirst()?.deleteFromRealm() + } + entriesToDelete.clear() + } + } + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt index 314f2002..0303eb2c 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomFieldEntry.kt @@ -2,10 +2,16 @@ package net.pokeranalytics.android.model.realm import android.content.Context import android.text.InputType +import io.realm.Realm import io.realm.RealmObject import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey +import io.realm.kotlin.where import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.ModelException +import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus +import net.pokeranalytics.android.model.interfaces.Manageable +import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor @@ -16,10 +22,10 @@ import java.util.* import java.util.Currency -open class CustomFieldEntry : RealmObject(), RowRepresentable { +open class CustomFieldEntry : RealmObject(), Manageable, RowRepresentable { @PrimaryKey - var id = UUID.randomUUID().toString() + override var id = UUID.randomUUID().toString() var order: Int = 0 var customField: CustomField? = null @@ -60,6 +66,40 @@ open class CustomFieldEntry : RealmObject(), RowRepresentable { ) } + override fun isValidForSave(): Boolean { + return true + } + + override fun alreadyExists(realm: Realm): Boolean { + return realm.where(this::class.java).notEqualTo("id", this.id).findAll().isNotEmpty() + } + + override fun getFailedSaveMessage(status: SaveValidityStatus): Int { + throw ModelException("${this::class.java} getFailedSaveMessage for $status not handled") + } + + override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int { + return R.string.cf_entry_delete_popup_message + } + + override fun deleteDependencies() { + if (isValid) { + val entries = realm.where().equalTo("customField.id", id).findAll() + entries.deleteAllFromRealm() + } + } + + override fun updateValue(value: Any?, row: RowRepresentable) { + this.value = value as String? ?: "" + } + + override fun isValidForDelete(realm: Realm): Boolean { + if (realm.where().contains("customFieldEntries.id", id).findAll().isNotEmpty()) { + return false + } + return true + } + /** * Return the amount */ diff --git a/app/src/main/java/net/pokeranalytics/android/ui/extensions/UIExtensions.kt b/app/src/main/java/net/pokeranalytics/android/ui/extensions/UIExtensions.kt index e0c1e576..ce769da5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/extensions/UIExtensions.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/extensions/UIExtensions.kt @@ -24,10 +24,6 @@ import net.pokeranalytics.android.util.billing.AppGuard import java.io.File - - - - // Sizes val Int.dp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt() @@ -70,8 +66,9 @@ fun PokerAnalyticsActivity.openPlayStorePage() { } // Open email for "Contact us" -fun PokerAnalyticsActivity.openContactMail(subjectStringRes: Int, filePath: String?= null) { - val info = "v${BuildConfig.VERSION_NAME}(${BuildConfig.VERSION_CODE}) - ${AppGuard.isProUser}, Android ${android.os.Build.VERSION.SDK_INT}, ${DeviceUtils.getDeviceName()}" +fun PokerAnalyticsActivity.openContactMail(subjectStringRes: Int, filePath: String? = null) { + val info = + "v${BuildConfig.VERSION_NAME}(${BuildConfig.VERSION_CODE}) - ${AppGuard.isProUser}, Android ${android.os.Build.VERSION.SDK_INT}, ${DeviceUtils.getDeviceName()}" val emailIntent = Intent(Intent.ACTION_SEND) @@ -105,6 +102,7 @@ fun PokerAnalyticsActivity.openUrl(url: String) { fun PokerAnalyticsActivity.showAlertDialog(title: Int? = null, message: Int? = null) { showAlertDialog(this, title, message) } + fun PokerAnalyticsFragment.showAlertDialog(title: Int? = null, message: Int? = null) { context?.let { showAlertDialog(it, title, message) @@ -114,7 +112,10 @@ fun PokerAnalyticsFragment.showAlertDialog(title: Int? = null, message: Int? = n /** * Create and show an alert dialog */ -fun showAlertDialog(context: Context, title: Int? = null, message: Int? = null) { +fun showAlertDialog( + context: Context, title: Int? = null, message: Int? = null, showCancelButton: Boolean = false, + positiveAction: (() -> Unit)? = null, negativeAction: (() -> Unit)? = null +) { val builder = AlertDialog.Builder(context) title?.let { builder.setTitle(title) @@ -122,7 +123,14 @@ fun showAlertDialog(context: Context, title: Int? = null, message: Int? = null) message?.let { builder.setMessage(message) } - builder.setPositiveButton(net.pokeranalytics.android.R.string.ok, null) + builder.setPositiveButton(net.pokeranalytics.android.R.string.ok) { _, _ -> + positiveAction?.invoke() + } + if (showCancelButton) { + builder.setNegativeButton(R.string.cancel) { _, _ -> + negativeAction?.invoke() + } + } builder.show() } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt index 29c89ad5..69e2cfd6 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt @@ -62,6 +62,7 @@ open class DeletableItemFragment : RealmFragment() { deletedItem = getRealm().copyFromRealm(itemToDelete) lastDeletedItemPosition = itemPosition getRealm().executeTransaction { + itemToDelete.deleteDependencies() itemToDelete.deleteFromRealm() } itemHasBeenReInserted = false diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt index c5d18e73..65f0f9bb 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt @@ -8,20 +8,24 @@ import androidx.interpolator.view.animation.FastOutSlowInInterpolator import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import com.google.android.material.chip.ChipGroup +import io.realm.kotlin.where import kotlinx.android.synthetic.main.fragment_custom_view.* import net.pokeranalytics.android.R import net.pokeranalytics.android.model.realm.CustomField import net.pokeranalytics.android.model.realm.CustomFieldEntry +import net.pokeranalytics.android.model.realm.Session 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 import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow import net.pokeranalytics.android.util.NULL_TEXT +import timber.log.Timber import java.util.* import kotlin.collections.ArrayList @@ -36,8 +40,7 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa return this.item as CustomField } - private val oldRows: ArrayList = ArrayList() - private val currentEntriesOrder: ArrayList = ArrayList() + private val deletedCustomFieldEntries: ArrayList = ArrayList() private val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() { @@ -74,7 +77,15 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa return true } - override fun onMoved(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, fromPos: Int, target: RecyclerView.ViewHolder, toPos: Int, x: Int, y: Int) { + override fun onMoved( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder, + fromPos: Int, + target: RecyclerView.ViewHolder, + toPos: Int, + x: Int, + y: Int + ) { super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y) Collections.swap(customField.entries, fromPos - (CustomFieldRow.values().size + 1), toPos - (CustomFieldRow.values().size + 1)) @@ -157,7 +168,7 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa override fun onRowValueChanged(value: Any?, row: RowRepresentable) { when (row) { is CustomFieldEntry -> { - row.value = value as String? ?: "" + row.updateValue(value, row) customField.updateRowRepresentation() rowRepresentableAdapter.notifyDataSetChanged() } @@ -174,12 +185,26 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa super.onRowDeleted(row) when (row) { is CustomFieldEntry -> { + if (!row.isValidForDelete(getRealm())) { + val status = row.getDeleteStatus(getRealm()) + val message = row.getFailedDeleteMessage(status) + showAlertDialog(requireContext(), R.string.cf_entry_delete_popup_title, message, showCancelButton = true, positiveAction = { + customField.deleteEntry(row) + rowRepresentableAdapter.notifyDataSetChanged() + }) + return + } customField.deleteEntry(row) rowRepresentableAdapter.notifyDataSetChanged() } } } + override fun onDataSaved() { + super.onDataSaved() + customField.cleanDeletedEntries(getRealm()) + } + /** * Init UI */ @@ -194,7 +219,7 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa itemTouchHelper.attachToRecyclerView(null) } - when(customField.sortCondition) { + when (customField.sortCondition) { CustomField.Sort.DEFAULT.uniqueIdentifier -> sortDefault.isChecked = true CustomField.Sort.ASCENDING.uniqueIdentifier -> sortAscending.isChecked = true CustomField.Sort.DESCENDING.uniqueIdentifier -> sortDescending.isChecked = true @@ -215,7 +240,7 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa return } - when(checkedId) { + when (checkedId) { R.id.sortDefault -> customField.sortCondition = CustomField.Sort.DEFAULT.uniqueIdentifier R.id.sortAscending -> customField.sortCondition = CustomField.Sort.ASCENDING.uniqueIdentifier R.id.sortDescending -> customField.sortCondition = CustomField.Sort.DESCENDING.uniqueIdentifier @@ -238,8 +263,18 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa onRowSelected(0, it) } } + + + val entries = getRealm().where().equalTo("customField.id", customField.id).findAll() + Timber.d("delete customField: entries: ${entries.size}") + entries.forEach { + val sessions = getRealm().where().contains("customFieldEntries.id", it.id).findAll() + Timber.d("Sessions: ${sessions.size} with entry value: ${it.value}") + } + } + /** * Update UI */ diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/EditableDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/EditableDataFragment.kt index d9a131a8..bbb837f9 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/EditableDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/EditableDataFragment.kt @@ -161,8 +161,8 @@ open class EditableDataFragment : RealmFragment(), RowRepresentableDelegate { val uniqueIdentifier = (managedItem as Savable).id finishActivityWithResult(uniqueIdentifier) } - } + onDataSaved() } else -> { val message = savable.getFailedSaveMessage(status) @@ -223,4 +223,6 @@ open class EditableDataFragment : RealmFragment(), RowRepresentableDelegate { this.primaryKey = primaryKey } + open fun onDataSaved() {} + } \ No newline at end of file