From 6910745e5b563f77de57b7eacb20e7f3b836de5f Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 17 May 2019 11:25:24 +0200 Subject: [PATCH] Realm sorted extensions added + refactoring + cleanup --- .../pokeranalytics/android/model/LiveData.kt | 91 ++----------------- .../android/model/realm/Filter.kt | 5 +- .../android/model/realm/Session.kt | 12 +-- .../ui/activity/EditableDataActivity.kt | 5 +- .../ui/fragment/BankrollDetailsFragment.kt | 2 +- .../android/ui/fragment/BankrollFragment.kt | 30 +++--- .../android/ui/fragment/DataListFragment.kt | 70 ++++++-------- .../android/ui/fragment/FeedFragment.kt | 3 +- .../android/ui/fragment/ReportsFragment.kt | 18 ++-- .../android/ui/fragment/SessionFragment.kt | 2 +- .../components/DeletableItemFragment.kt | 44 +++++++-- .../bottomsheet/BottomSheetFragment.kt | 50 ++++------ .../BottomSheetMultiSelectionFragment.kt | 4 +- .../ui/fragment/data/DataManagerFragment.kt | 4 +- .../ui/fragment/data/EditableDataFragment.kt | 4 +- .../fragment/data/TransactionDataFragment.kt | 8 +- .../android/util/RealmExtensions.kt | 71 +++++++++++++++ 17 files changed, 219 insertions(+), 204 deletions(-) create mode 100644 app/src/main/java/net/pokeranalytics/android/util/RealmExtensions.kt diff --git a/app/src/main/java/net/pokeranalytics/android/model/LiveData.kt b/app/src/main/java/net/pokeranalytics/android/model/LiveData.kt index 8209cd7c..c4863212 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/LiveData.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/LiveData.kt @@ -2,13 +2,9 @@ package net.pokeranalytics.android.model import android.content.Context import io.realm.Realm -import io.realm.RealmObject -import io.realm.RealmResults -import io.realm.Sort -import io.realm.kotlin.where +import io.realm.RealmModel import net.pokeranalytics.android.R -import net.pokeranalytics.android.model.interfaces.CountableUsage -import net.pokeranalytics.android.model.interfaces.Deletable +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.ui.view.Localizable @@ -27,74 +23,7 @@ enum class LiveData : Localizable { CUSTOM_FIELD, REPORT_SETUP; - fun items(realm: Realm, fieldName: String? = null, sortOrder: Sort? = null): RealmResults<*> { - val results = realm.where(this.relatedEntity).findAll().sort(fieldName ?: this.sortingFieldName, sortOrder ?: this.sorting) - - if (results.size > 0) { - if (results.first() is CountableUsage) { - this.setUseCount(realm, results) - return results.sort("useCount", Sort.DESCENDING) - } - } - return results - } - - fun setUseCount(realm: Realm, realmResults: RealmResults<*>) { - realm.executeTransaction { - realmResults.forEach { countableUsage -> - - when (this) { - TOURNAMENT_FEATURE -> { - (countableUsage as CountableUsage).useCount = it.where().contains( - "tournamentFeatures.id", - countableUsage.id - ).count().toInt() - } - else -> { - (countableUsage as CountableUsage).useCount = it.where().equalTo( - "${relatedEntity.simpleName.decapitalize()}.id", - countableUsage.id - ).count().toInt() - } - } - - } - } - } - - /** - * Return a copy of a RealmResults - */ - fun itemsArray(realm: Realm, fieldName: String? = null, sortOrder: Sort? = null): ArrayList<*> { - val results: ArrayList = ArrayList() - results.addAll( - realm.copyFromRealm( - realm.where(this.relatedEntity).findAll().sort( - fieldName ?: this.sortingFieldName, sortOrder ?: this.sorting - ) - ) - ) - - return results - } - - private val sortingFieldName: String - get() { - return when (this) { - TRANSACTION -> "date" - else -> "name" - } - } - - private val sorting: Sort - get() { - return when (this) { - TRANSACTION -> Sort.DESCENDING - else -> Sort.ASCENDING - } - } - - private val relatedEntity: Class + val relatedEntity: Class get() { return when (this) { BANKROLL -> Bankroll::class.java @@ -110,12 +39,8 @@ enum class LiveData : Localizable { } } - fun deleteData(realm: Realm, data: Deletable) { - realm.where(this.relatedEntity).equalTo("id", data.id).findAll().deleteAllFromRealm() - } - - fun updateOrCreate(realm: Realm, primaryKey: String?): RealmObject { - val proxyItem: RealmObject? = this.getData(realm, primaryKey) + fun updateOrCreate(realm: Realm, primaryKey: String?): RealmModel { + val proxyItem: Identifiable? = this.getData(realm, primaryKey) proxyItem?.let { return realm.copyFromRealm(it) } ?: run { @@ -123,12 +48,12 @@ enum class LiveData : Localizable { } } - fun newEntity(): RealmObject { + private fun newEntity(): RealmModel{ return this.relatedEntity.newInstance() } - fun getData(realm: Realm, primaryKey: String?): RealmObject? { - var proxyItem: RealmObject? = null + fun getData(realm: Realm, primaryKey: String?): Identifiable? { + var proxyItem: Identifiable? = null primaryKey?.let { val t = realm.where(this.relatedEntity).equalTo("id", it).findFirst() t?.let { 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..ce6d346f 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.model.interfaces.Identifiable import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow import java.util.* @@ -16,7 +17,7 @@ import java.util.* * It contains a list of [FilterCondition] describing the complete query to launch * The [Filter] is working closely with a [Filterable] interface providing the entity we want the query being launched on */ -open class Filter : RealmObject(), RowRepresentable { +open class Filter : RealmObject(), RowRepresentable, Identifiable { companion object { @@ -47,7 +48,7 @@ open class Filter : RealmObject(), RowRepresentable { } @PrimaryKey - var id = UUID.randomUUID().toString() + override var id = UUID.randomUUID().toString() // the queryWith name var name: String = "" 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..8b257246 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 @@ -18,7 +18,6 @@ import net.pokeranalytics.android.calculus.StatFormattingException import net.pokeranalytics.android.calculus.TextFormat import net.pokeranalytics.android.exceptions.ModelException import net.pokeranalytics.android.model.Limit -import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.TableSize import net.pokeranalytics.android.model.TournamentType import net.pokeranalytics.android.model.extensions.SessionState @@ -39,6 +38,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 net.pokeranalytics.android.util.sorted import java.text.DateFormat import java.util.* import java.util.Currency @@ -748,32 +748,32 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat SessionRow.BANKROLL -> row.editingDescriptors( mapOf( "defaultValue" to this.bankroll, - "data" to LiveData.BANKROLL.items(realm) + "data" to realm.sorted() // LiveData.BANKROLL.items(realm) ) ) SessionRow.GAME -> row.editingDescriptors( mapOf( "limit" to this.limit, "defaultValue" to this.game, - "data" to LiveData.GAME.items(realm) + "data" to realm.sorted() //LiveData.GAME.items(realm) ) ) SessionRow.LOCATION -> row.editingDescriptors( mapOf( "defaultValue" to this.location, - "data" to LiveData.LOCATION.items(realm) + "data" to realm.sorted() // LiveData.LOCATION.items(realm) ) ) SessionRow.TOURNAMENT_FEATURE -> row.editingDescriptors( mapOf( "defaultValue" to this.tournamentFeatures, - "data" to LiveData.TOURNAMENT_FEATURE.items(realm) + "data" to realm.sorted() //LiveData.TOURNAMENT_FEATURE.items(realm) ) ) SessionRow.TOURNAMENT_NAME -> row.editingDescriptors( mapOf( "defaultValue" to this.tournamentName, - "data" to LiveData.TOURNAMENT_NAME.items(realm) + "data" to realm.sorted() //LiveData.TOURNAMENT_NAME.items(realm) ) ) SessionRow.TOURNAMENT_TYPE -> row.editingDescriptors( diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/EditableDataActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/EditableDataActivity.kt index b3ecc525..a8af3f8a 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/EditableDataActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/EditableDataActivity.kt @@ -10,6 +10,7 @@ import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.fragment.data.* class EditableDataActivity : PokerAnalyticsActivity() { + enum class IntentKey(val keyName: String) { DATA_TYPE("DATA_TYPE"), PRIMARY_KEY("PRIMARY_KEY"); @@ -31,9 +32,9 @@ class EditableDataActivity : PokerAnalyticsActivity() { /** * Create a new instance for result */ - fun newInstanceForResult(fragment: Fragment, dataType: Int, primaryKey: String? = null, requestCode: Int) { + fun newInstanceForResult(fragment: Fragment, dataType: LiveData, primaryKey: String? = null, requestCode: Int) { val intent = Intent(fragment.requireContext(), EditableDataActivity::class.java) - intent.putExtra(IntentKey.DATA_TYPE.keyName, dataType) + intent.putExtra(IntentKey.DATA_TYPE.keyName, dataType.ordinal) primaryKey?.let { intent.putExtra(IntentKey.PRIMARY_KEY.keyName, it) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt index 7d0e195c..08fde005 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt @@ -170,7 +170,7 @@ class BankrollDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable * Open Bankroll edit activity */ private fun editBankroll() { - EditableDataActivity.newInstanceForResult(this, LiveData.BANKROLL.ordinal, bankrollReport.setup.bankroll?.id, REQUEST_CODE_EDIT) + EditableDataActivity.newInstanceForResult(this, LiveData.BANKROLL, bankrollReport.setup.bankroll?.id, REQUEST_CODE_EDIT) } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt index b68674d7..dcd74dff 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt @@ -37,6 +37,7 @@ import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.GraphRow +import net.pokeranalytics.android.util.sorted import timber.log.Timber import java.util.* import kotlin.collections.ArrayList @@ -60,7 +61,7 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour } private lateinit var parentActivity: PokerAnalyticsActivity - private lateinit var bankrollAdapter: RowRepresentableAdapter +// private lateinit var dataListAdapter: RowRepresentableAdapter private var rows: ArrayList = ArrayList() private var bankrollReportForRow: HashMap = HashMap() @@ -68,6 +69,12 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour private var lastItemClickedId: String = "" private var deletedRow: RowRepresentable? = null + private lateinit var bankrolls: RealmResults + + override fun deletableItems() : List { + return this.bankrolls + } + // Life Cycle override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -89,7 +96,7 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour itemToDeleteId?.let { id -> GlobalScope.launch(Dispatchers.Main) { delay(300) - deleteItem(bankrollAdapter, LiveData.BANKROLL.items(getRealm()), id) + deleteItem(dataListAdapter, bankrolls, id) } } @@ -129,6 +136,9 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour */ private fun initData() { + val realm = getRealm() + this.bankrolls = realm.sorted() + rows.clear() bankrollReportForRow.clear() @@ -153,7 +163,7 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour Timber.d("initData: ${System.currentTimeMillis() - startDate.time}ms") - val bankrolls = LiveData.BANKROLL.items(getRealm()) as RealmResults +// val bankrolls = LiveData.BANKROLL.items(getRealm()) as RealmResults bankrolls.forEach { bankroll -> val bankrollReportSetup = BankrollReportSetup(bankroll) @@ -168,7 +178,7 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour } if (!isDetached) { - bankrollAdapter.notifyDataSetChanged() + dataListAdapter.notifyDataSetChanged() } } } @@ -186,20 +196,18 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true) setHasOptionsMenu(true) - bankrollAdapter = RowRepresentableAdapter(this, this) + dataListAdapter = RowRepresentableAdapter(this, this) val viewManager = LinearLayoutManager(requireContext()) recyclerView.apply { setHasFixedSize(true) layoutManager = viewManager - adapter = bankrollAdapter + adapter = dataListAdapter } addButton.setOnClickListener { - LiveData.BANKROLL?.let { - EditableDataActivity.newInstanceForResult(this@BankrollFragment, dataType = it.ordinal, primaryKey = null, requestCode = REQUEST_CODE_CREATE) - } + EditableDataActivity.newInstanceForResult(this@BankrollFragment, dataType = LiveData.BANKROLL, primaryKey = null, requestCode = REQUEST_CODE_CREATE) } } @@ -207,7 +215,7 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour lastItemClickedPosition = rows.indexOfFirst { if (it is Identifiable) it.id == lastItemClickedId else false } deletedRow = rows.find { if (it is Identifiable) it.id == lastItemClickedId else false } rows.removeAt(lastItemClickedPosition) - bankrollAdapter.notifyItemRemoved(lastItemClickedPosition) + dataListAdapter.notifyItemRemoved(lastItemClickedPosition) } override fun updateUIAfterUndoDeletion(newItem: RealmObject) { @@ -221,7 +229,7 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour bankrollReportForRow[row] = bankrollReport rows.add(lastItemClickedPosition, row) - bankrollAdapter.notifyItemInserted(lastItemClickedPosition) + dataListAdapter.notifyItemInserted(lastItemClickedPosition) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt index fa4d9203..793491ac 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt @@ -10,15 +10,10 @@ import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import io.realm.RealmResults import kotlinx.android.synthetic.main.fragment_data_list.* -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch import net.pokeranalytics.android.R import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.realm.Filter -import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.EditableDataActivity import net.pokeranalytics.android.ui.activity.FiltersActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity @@ -29,6 +24,8 @@ import net.pokeranalytics.android.ui.fragment.components.DeletableItemFragment import net.pokeranalytics.android.ui.helpers.SwipeToDeleteCallback import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType +import net.pokeranalytics.android.util.sorted + class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource, RowRepresentableDelegate { @@ -36,20 +33,28 @@ class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource const val REQUEST_CODE_DETAILS = 1000 } + private lateinit var identifiableClass: Class + private lateinit var dataType: LiveData - private lateinit var items: RealmResults<*> - private lateinit var dataListAdapter: RowRepresentableAdapter - private var lastItemClickedId: String = "" + private lateinit var items: RealmResults + + override fun deletableItems() : List { + return this.items + } /** * Set fragment data */ fun setData(dataType: Int) { + this.dataType = LiveData.values()[dataType] + this.identifiableClass = this.dataType.relatedEntity + + val realm = getRealm() + this.items = realm.sorted(this.identifiableClass) + this.toolbar.title = this.dataType.localizedTitle(requireContext()) - this.dataType?.let { - this.items = it.items(getRealm()) - } + } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -62,7 +67,6 @@ class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource initUI() } - /** * Init UI */ @@ -95,28 +99,11 @@ class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource } this.addButton.setOnClickListener { - this.dataType?.let { - EditableDataActivity.newInstance( - requireContext(), - dataType = it.ordinal, - primaryKey = null - ) - } - } - } - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - if (requestCode == REQUEST_CODE_DETAILS && resultCode == Activity.RESULT_OK) { - - val itemToDeleteId = data?.getStringExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName) - itemToDeleteId?.let { id -> - GlobalScope.launch(Dispatchers.Main) { - delay(300) - deleteItem(dataListAdapter, items, id) - } - } - + EditableDataActivity.newInstance( + requireContext(), + dataType = this.dataType.ordinal, + primaryKey = null + ) } } @@ -139,21 +126,24 @@ class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource } override fun indexForRow(row: RowRepresentable): Int { - return this.items.indexOf(row) + return this.items.indexOf(row as Identifiable) } override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { - this.dataType?.let { - if (it == LiveData.FILTER) { + + when (this.dataType) { + LiveData.FILTER -> { val intent = Intent() intent.putExtra(FiltersActivity.IntentKey.FILTER_ID.keyName, (row as Filter).id) activity?.setResult(Activity.RESULT_OK, intent) activity?.finish() - } else { - lastItemClickedId = (row as Identifiable).id - EditableDataActivity.newInstanceForResult(this, it.ordinal, lastItemClickedId, REQUEST_CODE_DETAILS) + } + else -> { + val identifier = (row as Identifiable).id + EditableDataActivity.newInstanceForResult(this, this.dataType, identifier, REQUEST_CODE_DETAILS) } } + } } \ No newline at end of file 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..3c7fb223 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 @@ -106,7 +105,7 @@ class FeedFragment : RealmFragment(), RowRepresentableDelegate, FilterHandler { is Transaction -> { selectedTransaction = row selectedTransactionPosition = position - EditableDataActivity.newInstanceForResult(this, LiveData.TRANSACTION.ordinal, row.id, REQUEST_CODE_TRANSACTION_DETAILS) + EditableDataActivity.newInstanceForResult(this, LiveData.TRANSACTION, row.id, REQUEST_CODE_TRANSACTION_DETAILS) } } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt index dca332b3..00594ac2 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt @@ -19,8 +19,8 @@ import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.model.Criteria -import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.combined +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.realm.ReportSetup import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.ReportCreationActivity @@ -38,10 +38,14 @@ import java.util.* class ReportsFragment : DeletableItemFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { - private lateinit var reportsAdapter: RowRepresentableAdapter + // private lateinit var dataListAdapter: RowRepresentableAdapter private lateinit var reportSetups: RealmResults private var adapterRows = mutableListOf() + override fun deletableItems(): List { + return this.reportSetups + } + companion object { /** @@ -83,7 +87,7 @@ class ReportsFragment : DeletableItemFragment(), StaticRowRepresentableDataSourc itemToDeleteId?.let { id -> GlobalScope.launch(Dispatchers.Main) { delay(300) - deleteItem(reportsAdapter, LiveData.REPORT_SETUP.items(getRealm()), id) + deleteItem(dataListAdapter, reportSetups, id) } } } @@ -107,14 +111,14 @@ class ReportsFragment : DeletableItemFragment(), StaticRowRepresentableDataSourc */ private fun initUI() { - reportsAdapter = RowRepresentableAdapter(this, this) + dataListAdapter = RowRepresentableAdapter(this, this) val viewManager = LinearLayoutManager(requireContext()) recyclerView.apply { setHasFixedSize(true) layoutManager = viewManager - adapter = reportsAdapter + adapter = dataListAdapter } this.addButton.setOnClickListener { @@ -125,14 +129,14 @@ class ReportsFragment : DeletableItemFragment(), StaticRowRepresentableDataSourc // Rows - fun updateRows() { + private fun updateRows() { this.adapterRows.clear() if (this.reportSetups.size > 0) { adapterRows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.custom)) adapterRows.addAll(this.reportSetups) } adapterRows.addAll(ReportRow.getRows()) - this.reportsAdapter.notifyDataSetChanged() + this.dataListAdapter.notifyDataSetChanged() } override fun adapterRows(): List? { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt index f6aaa248..fdd43121 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt @@ -298,7 +298,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate { * Add new custom field */ private fun addNewCustomField() { - EditableDataActivity.newInstanceForResult(this, LiveData.CUSTOM_FIELD.ordinal, requestCode = REQUEST_CODE_NEW_CUSTOM_FIELD) + EditableDataActivity.newInstanceForResult(this, LiveData.CUSTOM_FIELD, requestCode = REQUEST_CODE_NEW_CUSTOM_FIELD) } /** 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 50bff679..ef64c652 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 @@ -1,28 +1,43 @@ package net.pokeranalytics.android.ui.fragment.components +import android.app.Activity +import android.content.Intent import android.os.Bundle import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import com.google.android.material.snackbar.Snackbar import io.realm.RealmObject +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import net.pokeranalytics.android.R import net.pokeranalytics.android.model.interfaces.Deletable import net.pokeranalytics.android.model.interfaces.Identifiable +import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter /** * Deletable Item Fragment * Don't forget to add a CoordinatorLayout at the top of your XML if you want to display correctly the snack bar */ -open class DeletableItemFragment : RealmFragment() { +abstract class DeletableItemFragment : RealmFragment() { + + companion object { + const val REQUEST_CODE_DELETION = 1000 + } + + lateinit var dataListAdapter: RowRepresentableAdapter private var deletedItem: RealmObject? = null private var lastDeletedItemPosition: Int = 0 - private var dataListAdapter: RowRepresentableAdapter? = null + private var mainLayout: ViewGroup? = null private var snackBar: Snackbar? = null + abstract fun deletableItems() : List + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) this.mainLayout = view.findViewById(R.id.mainLayout) @@ -33,6 +48,21 @@ open class DeletableItemFragment : RealmFragment() { snackBar?.dismiss() } + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == REQUEST_CODE_DELETION && resultCode == Activity.RESULT_OK) { + + val itemToDeleteId = data?.getStringExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName) + itemToDeleteId?.let { id -> + GlobalScope.launch(Dispatchers.Main) { + delay(300) + deleteItem(dataListAdapter, deletableItems(), id) + } + } + + } + } + /** * Delete item * [dataListAdapter]: Adapter to update @@ -40,7 +70,7 @@ open class DeletableItemFragment : RealmFragment() { * [itemId]: Id of the item to delete * [container]: View to display the Snackbar */ - fun deleteItem(dataListAdapter: RowRepresentableAdapter, items: List<*>, itemId: String) { + fun deleteItem(dataListAdapter: RowRepresentableAdapter, items: List, itemId: String) { if (isDetached || activity == null) { return @@ -49,8 +79,8 @@ open class DeletableItemFragment : RealmFragment() { this.dataListAdapter = dataListAdapter // Save the delete position & create a copy of the object - val itemPosition = items.indexOfFirst { (it as Identifiable).id == itemId } - val itemToDelete = items.find { (it as Identifiable).id == itemId } + val itemPosition = items.indexOfFirst { it.id == itemId } + val itemToDelete = items.find { it.id == itemId } if (itemToDelete is RealmObject && itemPosition != -1) { @@ -102,14 +132,14 @@ open class DeletableItemFragment : RealmFragment() { * Called once the object has been deleted */ open fun updateUIAfterDeletion(itemPosition: Int) { - dataListAdapter?.notifyItemRemoved(itemPosition) + dataListAdapter.notifyItemRemoved(itemPosition) } /** * Called once the object has been restored */ open fun updateUIAfterUndoDeletion(newItem: RealmObject) { - dataListAdapter?.notifyItemInserted(lastDeletedItemPosition) + dataListAdapter.notifyItemInserted(lastDeletedItemPosition) } } \ No newline at end of file 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..75a0425f 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 @@ -12,7 +12,7 @@ import android.view.WindowManager import androidx.appcompat.view.ContextThemeWrapper import androidx.fragment.app.FragmentManager import com.google.android.material.bottomsheet.BottomSheetDialogFragment -import io.realm.RealmObject +import io.realm.RealmModel import kotlinx.android.synthetic.main.fragment_bottom_sheet.* import net.pokeranalytics.android.R import net.pokeranalytics.android.model.LiveData @@ -79,7 +79,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() { val primaryKey = data.getStringExtra(EditableDataActivity.IntentKey.PRIMARY_KEY.keyName) val pokerAnalyticsActivity = activity as PokerAnalyticsActivity val liveDataType = LiveData.values()[dataType] - val proxyItem: RealmObject? = liveDataType.getData(pokerAnalyticsActivity.getRealm(), primaryKey) + val proxyItem: RealmModel? = liveDataType.getData(pokerAnalyticsActivity.getRealm(), primaryKey) this.delegate.onRowValueChanged(proxyItem, this.row) dismiss() } @@ -112,38 +112,22 @@ open class BottomSheetFragment : BottomSheetDialogFragment() { true } bottomSheetToolbar.menu.findItem(R.id.actionAdd).setOnMenuItemClickListener { - when (row) { - SessionRow.GAME -> EditableDataActivity.newInstanceForResult( - this, - LiveData.GAME.ordinal, - requestCode = REQUEST_CODE_ADD_NEW_OBJECT - ) - SessionRow.BANKROLL, TransactionRow.BANKROLL -> EditableDataActivity.newInstanceForResult( - this, - LiveData.BANKROLL.ordinal, - requestCode = REQUEST_CODE_ADD_NEW_OBJECT - ) - SessionRow.LOCATION -> EditableDataActivity.newInstanceForResult( - this, - LiveData.LOCATION.ordinal, - requestCode = REQUEST_CODE_ADD_NEW_OBJECT - ) - SessionRow.TOURNAMENT_NAME -> EditableDataActivity.newInstanceForResult( - this, - LiveData.TOURNAMENT_NAME.ordinal, - requestCode = REQUEST_CODE_ADD_NEW_OBJECT - ) - SessionRow.TOURNAMENT_FEATURE -> EditableDataActivity.newInstanceForResult( - this, - LiveData.TOURNAMENT_FEATURE.ordinal, - requestCode = REQUEST_CODE_ADD_NEW_OBJECT - ) - TransactionRow.TYPE -> EditableDataActivity.newInstanceForResult( - this, - LiveData.TRANSACTION_TYPE.ordinal, - requestCode = REQUEST_CODE_ADD_NEW_OBJECT - ) + val liveData = when (row) { + SessionRow.GAME -> LiveData.GAME + SessionRow.BANKROLL, TransactionRow.BANKROLL -> LiveData.BANKROLL + SessionRow.LOCATION -> LiveData.LOCATION + SessionRow.TOURNAMENT_NAME -> LiveData.TOURNAMENT_NAME + SessionRow.TOURNAMENT_FEATURE -> LiveData.TOURNAMENT_FEATURE + TransactionRow.TYPE -> LiveData.TRANSACTION_TYPE + else -> throw IllegalStateException("row $row does not have an associated LiveData value") } + + EditableDataActivity.newInstanceForResult( + this, + liveData, + requestCode = REQUEST_CODE_ADD_NEW_OBJECT + ) + true } bottomSheetToolbar.menu.findItem(R.id.actionCheck).setOnMenuItemClickListener { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetMultiSelectionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetMultiSelectionFragment.kt index 42872569..5798656c 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetMultiSelectionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetMultiSelectionFragment.kt @@ -3,7 +3,7 @@ package net.pokeranalytics.android.ui.fragment.components.bottomsheet import android.app.Activity import android.content.Intent import io.realm.RealmList -import io.realm.RealmObject +import io.realm.RealmModel import net.pokeranalytics.android.exceptions.RowRepresentableEditDescriptorException import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.ui.activity.EditableDataActivity @@ -28,7 +28,7 @@ open class BottomSheetMultiSelectionFragment : BottomSheetListFragment() { val primaryKey = data.getStringExtra(EditableDataActivity.IntentKey.PRIMARY_KEY.keyName) val pokerAnalyticsActivity = activity as PokerAnalyticsActivity val liveDataType = LiveData.values()[dataType] - val proxyItem: RealmObject? = liveDataType.getData(pokerAnalyticsActivity.getRealm(), primaryKey) + val proxyItem: RealmModel? = liveDataType.getData(pokerAnalyticsActivity.getRealm(), primaryKey) selectedRows.add(proxyItem as RowRepresentable) dataAdapter.refreshRow(proxyItem as RowRepresentable) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt index 645112b9..1caa908d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt @@ -8,7 +8,7 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import androidx.appcompat.app.AlertDialog -import io.realm.RealmObject +import io.realm.RealmModel import net.pokeranalytics.android.R import net.pokeranalytics.android.exceptions.ConfigurationException import net.pokeranalytics.android.model.LiveData @@ -21,7 +21,7 @@ import net.pokeranalytics.android.ui.fragment.components.RealmFragment open class DataManagerFragment : RealmFragment() { - lateinit var item: RealmObject + lateinit var item: RealmModel lateinit var liveDataType: LiveData protected var primaryKey: String? = null 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 fe285215..5b28b85d 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 @@ -5,7 +5,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager -import io.realm.RealmObject +import io.realm.RealmModel import kotlinx.android.synthetic.main.fragment_editable_data.* import kotlinx.android.synthetic.main.fragment_editable_data.view.* import net.pokeranalytics.android.R @@ -66,7 +66,7 @@ open class EditableDataFragment : DataManagerFragment(), RowRepresentableDelegat parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true) setHasOptionsMenu(true) - val proxyItem: RealmObject? = this.liveDataType.getData(this.getRealm(), primaryKey) + val proxyItem: RealmModel? = this.liveDataType.getData(this.getRealm(), primaryKey) proxyItem?.let { //TODO: Localize this.appBar.toolbar.title = "Update ${this.liveDataType.localizedTitle(requireContext()).toLowerCase().capitalize()}" diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/TransactionDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/TransactionDataFragment.kt index faf25b93..20ffcd89 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/TransactionDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/TransactionDataFragment.kt @@ -6,8 +6,9 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import net.pokeranalytics.android.model.LiveData +import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Transaction +import net.pokeranalytics.android.model.realm.TransactionType import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.helpers.DateTimePickerManager @@ -17,6 +18,7 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.TransactionRow import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.extensions.round import net.pokeranalytics.android.util.extensions.shortDate +import net.pokeranalytics.android.util.sorted import java.util.* /** @@ -56,8 +58,8 @@ class TransactionDataFragment : EditableDataFragment(), StaticRowRepresentableDa override fun editDescriptors(row: RowRepresentable): ArrayList? { return when (row) { - TransactionRow.BANKROLL -> row.editingDescriptors(mapOf("defaultValue" to this.transaction.bankroll, "data" to LiveData.BANKROLL.items(getRealm()))) - TransactionRow.TYPE -> row.editingDescriptors(mapOf("defaultValue" to this.transaction.type, "data" to LiveData.TRANSACTION_TYPE.items(getRealm()))) + TransactionRow.BANKROLL -> row.editingDescriptors(mapOf("defaultValue" to this.transaction.bankroll, "data" to getRealm().sorted() )) + TransactionRow.TYPE -> row.editingDescriptors(mapOf("defaultValue" to this.transaction.type, "data" to getRealm().sorted() )) TransactionRow.AMOUNT -> row.editingDescriptors(mapOf("defaultValue" to (if (this.transaction.amount != 0.0) this.transaction.amount.round() else ""))) TransactionRow.COMMENT -> row.editingDescriptors(mapOf("defaultValue" to this.transaction.comment)) else -> super.editDescriptors(row) diff --git a/app/src/main/java/net/pokeranalytics/android/util/RealmExtensions.kt b/app/src/main/java/net/pokeranalytics/android/util/RealmExtensions.kt new file mode 100644 index 00000000..5c458e7b --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/util/RealmExtensions.kt @@ -0,0 +1,71 @@ +package net.pokeranalytics.android.util + +import io.realm.Realm +import io.realm.RealmModel +import io.realm.RealmResults +import io.realm.Sort +import io.realm.kotlin.where +import net.pokeranalytics.android.model.interfaces.CountableUsage +import net.pokeranalytics.android.model.realm.Session +import net.pokeranalytics.android.model.realm.TournamentFeature +import net.pokeranalytics.android.model.realm.Transaction + +/** + * Returns all entities of the [clazz] sorted with their default sorting + */ +fun Realm.sorted(clazz: Class) : RealmResults { + + if (clazz is CountableUsage) { + this.updateUsageCount(clazz) + } + + val sortField = when (clazz) { + is CountableUsage -> "useCount" + is Transaction -> "date" + else -> "name" + } + val resultSort = when (clazz) { + is CountableUsage -> Sort.DESCENDING + is Transaction -> Sort.DESCENDING + else -> Sort.ASCENDING + } + + return this.where(clazz).findAll().sort(sortField, resultSort) +} + +/** + * Returns all entities of the [clazz] sorted with their default sorting + */ +inline fun Realm.sorted() : RealmResults { + return this.sorted(C::class.java) +} + +/** + * Updates the useCount variable of the CountableUsage entity + */ +fun Realm.updateUsageCount(clazz: Class) { + + val results = this.where(clazz).findAll() + this.executeTransaction { + results.forEach { countableUsage -> + + val countable = (countableUsage as CountableUsage) + when (clazz) { + is TournamentFeature -> { + countable.useCount = it.where().contains( + "tournamentFeatures.id", + countable.id + ).count().toInt() + } + else -> { + countable.useCount = it.where().equalTo( + "${clazz.simpleName.decapitalize()}.id", + countable.id + ).count().toInt() + } + } + + } + } + +} \ No newline at end of file