Realm sorted extensions added + refactoring + cleanup

dev
Laurent 7 years ago
parent 37913ced3f
commit 6910745e5b
  1. 91
      app/src/main/java/net/pokeranalytics/android/model/LiveData.kt
  2. 5
      app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt
  3. 12
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  4. 5
      app/src/main/java/net/pokeranalytics/android/ui/activity/EditableDataActivity.kt
  5. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt
  6. 30
      app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt
  7. 62
      app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt
  8. 3
      app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt
  9. 18
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt
  10. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt
  11. 44
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DeletableItemFragment.kt
  12. 46
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt
  13. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetMultiSelectionFragment.kt
  14. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt
  15. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/data/EditableDataFragment.kt
  16. 8
      app/src/main/java/net/pokeranalytics/android/ui/fragment/data/TransactionDataFragment.kt
  17. 71
      app/src/main/java/net/pokeranalytics/android/util/RealmExtensions.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<Session>().contains(
"tournamentFeatures.id",
countableUsage.id
).count().toInt()
}
else -> {
(countableUsage as CountableUsage).useCount = it.where<Session>().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<Any> = 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<out RealmObject>
val relatedEntity: Class<out Identifiable>
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 {

@ -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 = ""

@ -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<Bankroll>() // 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<Game>() //LiveData.GAME.items(realm)
)
)
SessionRow.LOCATION -> row.editingDescriptors(
mapOf(
"defaultValue" to this.location,
"data" to LiveData.LOCATION.items(realm)
"data" to realm.sorted<Location>() // 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<TournamentFeature>() //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<TournamentName>() //LiveData.TOURNAMENT_NAME.items(realm)
)
)
SessionRow.TOURNAMENT_TYPE -> row.editingDescriptors(

@ -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)
}

@ -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)
}
}

@ -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<RowRepresentable> = ArrayList()
private var bankrollReportForRow: HashMap<RowRepresentable, BankrollReport> = HashMap()
@ -68,6 +69,12 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour
private var lastItemClickedId: String = ""
private var deletedRow: RowRepresentable? = null
private lateinit var bankrolls: RealmResults<Bankroll>
override fun deletableItems() : List<Identifiable> {
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<Bankroll>
// val bankrolls = LiveData.BANKROLL.items(getRealm()) as RealmResults<Bankroll>
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)
}
}

@ -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<out Identifiable>
private lateinit var dataType: LiveData
private lateinit var items: RealmResults<*>
private lateinit var dataListAdapter: RowRepresentableAdapter
private var lastItemClickedId: String = ""
private lateinit var items: RealmResults<out Identifiable>
override fun deletableItems() : List<Identifiable> {
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,30 +99,13 @@ class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource
}
this.addButton.setOnClickListener {
this.dataType?.let {
EditableDataActivity.newInstance(
requireContext(),
dataType = it.ordinal,
dataType = this.dataType.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)
}
}
}
}
override fun onResume() {
super.onResume()
@ -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)
}
}
}
}

@ -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)
}
}
}

@ -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<ReportSetup>
private var adapterRows = mutableListOf<RowRepresentable>()
override fun deletableItems(): List<Identifiable> {
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<RowRepresentable>? {

@ -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)
}
/**

@ -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<Identifiable>
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<Identifiable>, 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)
}
}

@ -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(
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.TRANSACTION_TYPE.ordinal,
liveData,
requestCode = REQUEST_CODE_ADD_NEW_OBJECT
)
}
true
}
bottomSheetToolbar.menu.findItem(R.id.actionCheck).setOnMenuItemClickListener {

@ -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)
}

@ -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

@ -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()}"

@ -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<RowRepresentableEditDescriptor>? {
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<Bankroll>() ))
TransactionRow.TYPE -> row.editingDescriptors(mapOf("defaultValue" to this.transaction.type, "data" to getRealm().sorted<TransactionType>() ))
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)

@ -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 <T : RealmModel> Realm.sorted(clazz: Class<T>) : RealmResults<T> {
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 <reified C : RealmModel> Realm.sorted() : RealmResults<C> {
return this.sorted(C::class.java)
}
/**
* Updates the useCount variable of the CountableUsage entity
*/
fun <T : RealmModel>Realm.updateUsageCount(clazz: Class<T>) {
val results = this.where(clazz).findAll()
this.executeTransaction {
results.forEach { countableUsage ->
val countable = (countableUsage as CountableUsage)
when (clazz) {
is TournamentFeature -> {
countable.useCount = it.where<Session>().contains(
"tournamentFeatures.id",
countable.id
).count().toInt()
}
else -> {
countable.useCount = it.where<Session>().equalTo(
"${clazz.simpleName.decapitalize()}.id",
countable.id
).count().toInt()
}
}
}
}
}
Loading…
Cancel
Save