From 0b8062e4c5f5fd1a8f8ba5c5057971abf9efc255 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 1 Apr 2019 17:21:30 +0200 Subject: [PATCH] refactoring + fixing rates setting --- .../android/PokerAnalyticsApplication.kt | 62 +------------------ .../android/model/interfaces/Manageable.kt | 19 +++--- .../android/model/realm/Bankroll.kt | 6 +- .../android/model/realm/Currency.kt | 38 +++++++----- .../android/model/realm/Session.kt | 32 ++++++++-- .../android/ui/activity/HomeActivity.kt | 22 +++++++ .../components/PokerAnalyticsActivity.kt | 5 -- .../ui/fragment/BankrollDataFragment.kt | 21 ++++--- .../ui/fragment/EditableDataFragment.kt | 61 ++++++++++-------- .../android/ui/fragment/SessionFragment.kt | 2 - .../android/util/CurrencyUtils.kt | 10 +++ 11 files changed, 147 insertions(+), 131 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index 88189581..0804b039 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -5,7 +5,6 @@ import com.crashlytics.android.Crashlytics import io.fabric.sdk.android.Fabric import io.realm.Realm import io.realm.RealmConfiguration -import io.realm.RealmResults import io.realm.kotlin.where import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -40,7 +39,7 @@ class PokerAnalyticsApplication : Application() { } if (BuildConfig.DEBUG) { - this.createFakeSessions() // debug +// this.createFakeSessions() // debug } } @@ -61,63 +60,4 @@ class PokerAnalyticsApplication : Application() { } -// -// private fun createFakeStats() { -// -// val buyinList = arrayListOf(100.0, 200.0, 300.0, 500.0, 1000.0, 2000.0) -// val resultsList = arrayListOf( -// -2500.0, -2000.0, -1500.0, -1000.0, -500.0, 200.0, 1000.0, 1500.0, 2500.0 -// ) -// -// val commitFrequency = 100 -// -// Thread() { -// -// try { -// -// val realm = Realm.getDefaultInstance() -// -// // Test endedSessions -// val pstats = realm.where().findAll() -// if (pstats.size < 10) { -// -// val numberOfSessions = 2000 -// Timber.d("*** Start creating ${numberOfSessions} fake computables...") -// -// val s = Date() -// -// realm.beginTransaction() -// -// for (index in 0..numberOfSessions) { -// -// if (index % commitFrequency == 0) { -// Timber.d("****** committing at ${index} computables...") -// realm.commitTransaction() -// realm.beginTransaction() -// } -// -// val ps = realm.createObject(ComputableResult::class.java) -// ps.ratedBuyin = buyinList.random() -// ps.ratedNet = resultsList.random() -// -// } -// -// realm.commitTransaction() -// -// val e = Date() -// val duration = (e.time - s.time) / 1000.0 -// Timber.d("*** ended in ${duration} seconds") -// -// } -// -// realm.close() -// -// } catch (e: Exception) { -// Timber.e(e) -// } -// -// }.start() -// -// } - } \ No newline at end of file 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 e0a0cdc7..8531efc4 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 @@ -1,11 +1,9 @@ package net.pokeranalytics.android.model.interfaces -import io.realm.Realm +import io.realm.RealmModel import io.realm.RealmObject -import io.realm.kotlin.where import net.pokeranalytics.android.R import net.pokeranalytics.android.exceptions.ModelException -import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.ui.view.RowRepresentable enum class ManageableStatus { @@ -17,7 +15,7 @@ enum class ManageableStatus { /** * An interface to grouped object which are managed by the database */ -interface Manageable : Savable, Deletable, Identifiable, Editable +interface Manageable : Savable, Deletable, Editable interface NameManageable: Manageable { var name: String @@ -27,7 +25,10 @@ interface NameManageable: Manageable { } override fun alreadyExists(): Boolean { - return (this as RealmObject).realm.where((this as RealmObject)::class.java).equalTo("name", this.name).findAll().isNotEmpty() + if (this is RealmObject && this.realm != null) { + return (this as RealmObject).realm.where(this::class.java).equalTo("name", this.name).findAll().isNotEmpty() + } + return false } override fun getFailedSaveMessage(status: ManageableStatus): Int { @@ -43,7 +44,7 @@ interface NameManageable: Manageable { /** * An interface associate a unique identifier to an object */ -interface Identifiable { +interface Identifiable : RealmModel { /** * A unique identifier getter @@ -54,7 +55,7 @@ interface Identifiable { /** * An interface to update the fields of an object */ -interface Editable { +interface Editable : Identifiable { /** * a method to handle the modification of the object. * Through [RowRepresentable] the object is able to update the right variable with the new value. @@ -65,7 +66,7 @@ interface Editable { /** * An interface to easily handle the validity of any object we want to save */ -interface Savable { +interface Savable : Identifiable { fun isValidForSave(): Boolean fun alreadyExists(): Boolean @@ -96,7 +97,7 @@ interface Savable { /** * An interface to easily handle the validity of any object we want to delete */ -interface Deletable { +interface Deletable : Identifiable { /** * A method to define if an object is safe for deletion in database diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt index 45964727..72534702 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt @@ -82,7 +82,11 @@ open class Bankroll() : RealmObject(), NameManageable, StaticRowRepresentableDat this.currency?.code = value as String? } BankrollRow.RATE -> { - this.currency?.rate = (value as String? ?: "0").toDouble() + value?.let { rate -> + this.currency?.rate = (rate as String).toDouble() + } ?: run { + this.currency?.rate = null + } } } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt index adcaeee5..97e678b5 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt @@ -1,12 +1,15 @@ package net.pokeranalytics.android.model.realm -import io.realm.Realm import io.realm.RealmObject +import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey import java.util.* open class Currency : RealmObject() { + @Ignore + val DEFAULTRATE: Double = 1.0 + @PrimaryKey var id = UUID.randomUUID().toString() @@ -18,21 +21,26 @@ open class Currency : RealmObject() { /** * The rate of the currency with the main currency */ - var rate: Double? = 1.0 - - fun refreshAllRelatedComputableResults(realm:Realm) { - val rate = this.rate ?: 1.0 - val query = realm.where(ComputableResult::class.java) - query.`in`("session.bankroll.currency.id", arrayOf(this.id)) - val cResults = query.findAll() - cResults.forEach { computable -> - computable.session?.result?.net?.let { - computable.ratedNet = it * rate - } - computable.session?.result?.buyin?.let { - computable.ratedBuyin = it * rate - } + var rate: Double? = DEFAULTRATE + + fun refreshRelatedRatedValues() { + if (this.realm != null) { + + val rate = this.rate ?: DEFAULTRATE + val query = this.realm.where(ComputableResult::class.java) + query.`in`("session.bankroll.currency.id", arrayOf(this.id)) + val cResults = query.findAll() + cResults.forEach { computable -> + computable.session?.result?.net?.let { + computable.ratedNet = it * rate + } + computable.session?.result?.buyin?.let { + computable.ratedBuyin = it * rate + } + + } } + } } \ No newline at end of file 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 7f3902e6..e19c10ab 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 @@ -40,7 +40,7 @@ import java.util.* import java.util.Currency import kotlin.collections.ArrayList -open class Session : RealmObject(), Identifiable, Editable, StaticRowRepresentableDataSource, RowRepresentable, Timed, +open class Session : RealmObject(), Identifiable, Manageable, StaticRowRepresentableDataSource, RowRepresentable, Timed, TimeFilterable { enum class Type { @@ -367,6 +367,28 @@ open class Session : RealmObject(), Identifiable, Editable, StaticRowRepresentab throw ModelException("Session should have an existing Result relationship") } + // Manageable + + override fun isValidForSave(): Boolean { + return this.bankroll != null + } + + override fun alreadyExists(): Boolean { + return false + } + + override fun getFailedSaveMessage(status: ManageableStatus): Int { + return 0 // @todo + } + + override fun isValidForDelete(): Boolean { + return true + } + + override fun getFailedDeleteMessage(): Int { + return 0 // @todo + } + // States /** @@ -731,13 +753,13 @@ open class Session : RealmObject(), Identifiable, Editable, StaticRowRepresentab this.breakDuration = if (value != null) (value as String).toLong() * 60 * 1000 else 0 } SessionRow.BUY_IN -> { - val localResult = if (result != null) result as Result else realm.createObject(Result::class.java) + val localResult = if (this.result != null) this.result as Result else realm.createObject(Result::class.java) localResult.buyin = value as Double? - result = localResult + this.result = localResult this.updateRowRepresentation() } SessionRow.CASHED_OUT, SessionRow.PRIZE, SessionRow.NET_RESULT -> { - val localResult = if (result != null) result as Result else realm.createObject(Result::class.java) + val localResult = if (this.result != null) this.result as Result else realm.createObject(Result::class.java) if (value == null) { localResult.cashout = null @@ -746,7 +768,7 @@ open class Session : RealmObject(), Identifiable, Editable, StaticRowRepresentab this.end() } - result = localResult + this.result = localResult } SessionRow.COMMENT -> comment = value as String? ?: "" diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt index 3ced9609..9b689eef 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt @@ -7,8 +7,10 @@ import android.view.Menu import android.view.MenuItem import androidx.appcompat.app.AlertDialog import com.google.android.material.bottomnavigation.BottomNavigationView +import io.realm.RealmResults import kotlinx.android.synthetic.main.activity_home.* import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.realm.Currency import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.adapter.HomePagerAdapter import net.pokeranalytics.android.util.Preferences @@ -27,6 +29,8 @@ class HomeActivity : PokerAnalyticsActivity() { private var homeMenu: Menu? = null + private lateinit var currencies: RealmResults + private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> when (item.itemId) { net.pokeranalytics.android.R.id.navigation_history -> { @@ -49,6 +53,7 @@ class HomeActivity : PokerAnalyticsActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_home) + observeRealmObjects() initUI() checkFirstLaunch() } @@ -68,6 +73,23 @@ class HomeActivity : PokerAnalyticsActivity() { return super.onOptionsItemSelected(item) } + private fun observeRealmObjects() { + + val realm = getRealm() + + // observe currency changes + this.currencies = realm.where(Currency::class.java).findAll() + this.currencies.addChangeListener { t, set -> + + realm.beginTransaction() + t.forEach { + it.refreshRelatedRatedValues() + } + realm.commitTransaction() + } + + } + /** * Init UI */ diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/components/PokerAnalyticsActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/components/PokerAnalyticsActivity.kt index 9ad0b20e..8d177370 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/components/PokerAnalyticsActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/components/PokerAnalyticsActivity.kt @@ -3,7 +3,6 @@ package net.pokeranalytics.android.ui.activity.components import android.Manifest import android.Manifest.permission.ACCESS_FINE_LOCATION import android.content.pm.PackageManager -import android.os.Bundle import android.view.MenuItem import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat @@ -25,10 +24,6 @@ open class PokerAnalyticsActivity : AppCompatActivity() { private val realm = Realm.getDefaultInstance() private var permissionCallback: ((granted: Boolean) -> Unit)? = null - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - } - override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt index 1973e9c2..90831d09 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt @@ -17,9 +17,9 @@ import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.rowrepresentable.BankrollRow import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow +import net.pokeranalytics.android.util.CurrencyUtils import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.Preferences -import net.pokeranalytics.android.util.extensions.round import retrofit2.Call import retrofit2.Response import java.util.* @@ -93,10 +93,10 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS } } BankrollRow.RATE -> { - bankroll.currency?.let { - (it.rate ?: 1.0).round() + this.bankroll.currency?.rate?.let { rate -> + CurrencyUtils.getCurrencyRateFormatter().format(rate) } ?: run { - 1.0.round() + CurrencyUtils.getCurrencyRateFormatter().format(1.0) } } else -> super.stringForRow(row) @@ -114,7 +114,14 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS override fun editDescriptors(row: RowRepresentable): ArrayList? { return when (row) { SimpleRow.NAME -> row.editingDescriptors(mapOf("defaultValue" to this.bankroll.name)) - BankrollRow.RATE -> row.editingDescriptors(mapOf("defaultValue" to (this.bankroll.currency?.rate ?: 1.0).round())) + BankrollRow.RATE -> { + + this.bankroll.currency?.rate?.let { rate -> + row.editingDescriptors(mapOf("defaultValue" to CurrencyUtils.getCurrencyRateFormatter().format(rate))) + } ?: run { + row.editingDescriptors(mapOf("defaultValue" to "")) + } + } else -> null } } @@ -132,7 +139,7 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS // Clear the value when the currency has been updated if (row == BankrollRow.CURRENCY) { - lastRefreshRateCall = 0 + this.lastRefreshRateCall = 0 } updateAdapterUI() @@ -162,7 +169,7 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS rows.add(BankrollRow.LIVE) rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.currency)) rows.add(BankrollRow.CURRENCY) - if (differentCurrency) { + if (this.differentCurrency) { rows.add(BankrollRow.RATE) rows.add(BankrollRow.REFRESH_RATE) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt index 1667084a..c7dd2591 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt @@ -12,8 +12,10 @@ import kotlinx.android.synthetic.main.fragment_editable_data.view.* import net.pokeranalytics.android.R import net.pokeranalytics.android.exceptions.ConfigurationException import net.pokeranalytics.android.model.LiveData -import net.pokeranalytics.android.model.interfaces.* -import net.pokeranalytics.android.model.realm.Bankroll +import net.pokeranalytics.android.model.interfaces.Editable +import net.pokeranalytics.android.model.interfaces.Manageable +import net.pokeranalytics.android.model.interfaces.ManageableStatus +import net.pokeranalytics.android.model.interfaces.Savable import net.pokeranalytics.android.ui.activity.EditableDataActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter @@ -141,35 +143,42 @@ open class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDele * Save data */ fun saveData() { - if (this.item is Savable) { - val status = (this.item as Savable).saveStatus() - when (status) { - ManageableStatus.VALID -> { - this.getRealm().executeTransaction { - val item = it.copyToRealmOrUpdate(this.item) - - if (item is Bankroll) { - item.currency?.refreshAllRelatedComputableResults(it) - } - - val uniqueIdentifier = if (item is Identifiable) { - item.id - } else "" - finishActivityWithResult(uniqueIdentifier) + val savable = this.item + when (savable) { + is Savable -> { + val status = savable.saveStatus() + when (status) { + ManageableStatus.VALID -> { + this.getRealm().executeTransaction { + val managedItem = it.copyToRealmOrUpdate(this.item) + if (managedItem is Savable) { + val uniqueIdentifier = (managedItem as Savable).id + finishActivityWithResult(uniqueIdentifier) + } + +// if (managedItem is Bankroll) { +// managedItem.currency?.refreshRelatedRatedValues(it) +// } +// +// val uniqueIdentifier = (managedItem as Savable).id +// finishActivityWithResult(uniqueIdentifier) + } + } + else -> { + val message = savable.getFailedSaveMessage(status) + val builder = AlertDialog.Builder(requireContext()) + .setMessage(message) + .setNegativeButton(R.string.ok, null) + builder.show() } } - else -> { - val message = (this.item as Savable).getFailedSaveMessage(status) - val builder = AlertDialog.Builder(requireContext()) - .setMessage(message) - .setNegativeButton(R.string.ok, null) - builder.show() - } + + } else -> { + throw ConfigurationException("Save action called on un-Savable object") } - } else { - throw ConfigurationException("Save action called on un-Savable object") } + } /** 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 d4c7cd52..97e56d3d 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 @@ -204,8 +204,6 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate { sessionMenu?.findItem(R.id.restart)?.isVisible = true sessionMenu?.findItem(R.id.stop)?.isVisible = false } - else -> { - } } } diff --git a/app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt b/app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt index eaba67bd..861ada82 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt @@ -30,6 +30,16 @@ class CurrencyUtils { return currencyFormatter } + /** + * Get a currency rate formatter + */ + fun getCurrencyRateFormatter() : NumberFormat { + val currencyFormatter = NumberFormat.getInstance() + currencyFormatter.minimumFractionDigits = 0 + currencyFormatter.maximumFractionDigits = 6 + return currencyFormatter + } + } } \ No newline at end of file