Merge branch 'dev' of gitlab.com:stax-river/poker-analytics into dev

dev
Aurelien Hubert 7 years ago
commit 3364065ea6
  1. 16
      app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt
  2. 9
      app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt
  3. 9
      app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt
  4. 28
      app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt
  5. 4
      app/src/main/java/net/pokeranalytics/android/model/realm/TimeFrame.kt
  6. 18
      app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt
  7. 7
      app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt
  8. 3
      app/src/main/java/net/pokeranalytics/android/ui/activity/ProgressReportActivity.kt
  9. 5
      app/src/main/java/net/pokeranalytics/android/ui/activity/ReportCreationActivity.kt
  10. 11
      app/src/main/java/net/pokeranalytics/android/ui/activity/components/Codes.kt
  11. 4
      app/src/main/java/net/pokeranalytics/android/ui/activity/components/ReportActivity.kt
  12. 11
      app/src/main/java/net/pokeranalytics/android/ui/extensions/UIExtensions.kt
  13. 7
      app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt
  14. 14
      app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt
  15. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt
  16. 22
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt
  17. 6
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt
  18. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComposableTableReportFragment.kt
  19. 12
      app/src/main/java/net/pokeranalytics/android/ui/interfaces/FilterHandler.kt
  20. 0
      app/src/main/java/net/pokeranalytics/android/util/csv/CSVField.kt
  21. 10
      app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt
  22. 33
      app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt

@ -11,9 +11,7 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import net.pokeranalytics.android.model.migrations.Patcher import net.pokeranalytics.android.model.migrations.Patcher
import net.pokeranalytics.android.model.migrations.PokerAnalyticsMigration import net.pokeranalytics.android.model.migrations.PokerAnalyticsMigration
import net.pokeranalytics.android.model.realm.ComputableResult
import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.SessionSet
import net.pokeranalytics.android.model.utils.Seed import net.pokeranalytics.android.model.utils.Seed
import net.pokeranalytics.android.util.FakeDataManager import net.pokeranalytics.android.util.FakeDataManager
import net.pokeranalytics.android.util.PokerAnalyticsLogs import net.pokeranalytics.android.util.PokerAnalyticsLogs
@ -42,13 +40,11 @@ class PokerAnalyticsApplication : Application() {
.build() .build()
Realm.setDefaultConfiguration(realmConfiguration) Realm.setDefaultConfiguration(realmConfiguration)
val realm = Realm.getDefaultInstance() // val realm = Realm.getDefaultInstance()
realm.executeTransaction { // realm.executeTransaction {
realm.where(Session::class.java).findAll().deleteAllFromRealm() // realm.where(Session::class.java).findAll().deleteAllFromRealm()
realm.where(ComputableResult::class.java).findAll().deleteAllFromRealm() // }
realm.where(SessionSet::class.java).findAll().deleteAllFromRealm() // realm.close()
}
realm.close()
// Set up Crashlytics, disabled for debug builds // Set up Crashlytics, disabled for debug builds
val crashlyticsKit = Crashlytics.Builder() val crashlyticsKit = Crashlytics.Builder()
@ -65,7 +61,7 @@ class PokerAnalyticsApplication : Application() {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
Timber.d("UserPreferences.defaultCurrency: ${UserDefaults.currency.symbol}") Timber.d("UserPreferences.defaultCurrency: ${UserDefaults.currency.symbol}")
this.createFakeSessions() // this.createFakeSessions()
} }

@ -4,6 +4,7 @@ import android.content.Context
import io.realm.RealmQuery import io.realm.RealmQuery
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.util.NULL_TEXT
fun List<Query>.mapFirstCondition() : List<QueryCondition> { fun List<Query>.mapFirstCondition() : List<QueryCondition> {
return this.map { it.conditions.first() } return this.map { it.conditions.first() }
@ -41,6 +42,14 @@ class Query {
this._conditions.addAll(queryConditions) this._conditions.addAll(queryConditions)
} }
val defaultName: String
get() {
return when (this._conditions.size) {
0 -> NULL_TEXT
else -> this._conditions.joinToString("") { it.id.joinToString("") }
}
}
fun getName(context: Context): String { fun getName(context: Context): String {
return when (this._conditions.size) { return when (this._conditions.size) {
0 -> context.getString(R.string.all_sessions) // @todo should be dependant of the underlying type, ie. Session, Transaction... 0 -> context.getString(R.string.all_sessions) // @todo should be dependant of the underlying type, ie. Session, Transaction...

@ -124,13 +124,16 @@ class PokerAnalyticsMigration : RealmMigration {
} }
} }
schema.get("Session")?.let { schema.get("Session")?.let {
it.addField("startDateHourMinuteComponent", Double::class.java).setNullable("startDateHourMinuteComponent", true) it.addField("startDateHourMinuteComponent", Double::class.java)
it.addField("endDateHourMinuteComponent", Double::class.java).setNullable("endDateHourMinuteComponent", true) .setNullable("startDateHourMinuteComponent", true)
it.addField("endDateHourMinuteComponent", Double::class.java)
.setNullable("endDateHourMinuteComponent", true)
it.addRealmListField("customFieldEntries", CustomFieldEntry::class.java) it.addRealmListField("customFieldEntries", CustomFieldEntry::class.java)
} }
schema.get("Filter")?.addField("filterableTypeOrdinal", Integer::class.java) schema.get("Filter")?.addField("filterableTypeOrdinal", Integer::class.java)
schema.get("Filter")?.addField("useCount", Int::class.java)
schema.get("Filter")?.removeField("usageCount")
currentVersion++ currentVersion++
} }
} }

@ -8,15 +8,14 @@ import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.filter.Filterable import net.pokeranalytics.android.model.filter.Filterable
import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.CountableUsage
import net.pokeranalytics.android.model.interfaces.Deletable import net.pokeranalytics.android.model.interfaces.Deletable
import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus
import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.ui.interfaces.FilterableType import net.pokeranalytics.android.ui.interfaces.FilterableType
import net.pokeranalytics.android.ui.view.ImageDecorator import net.pokeranalytics.android.ui.view.ImageDecorator
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
import net.pokeranalytics.android.util.Preferences
import java.util.* import java.util.*
/** /**
@ -24,7 +23,7 @@ import java.util.*
* It contains a list of [FilterCondition] describing the complete query to launch * It contains a list of [FilterCondition] describing the complete query to launch
* The [Filter] is working closely with a [Filterable] interface providing the entity we want the query being launched on * The [Filter] is working closely with a [Filterable] interface providing the entity we want the query being launched on
*/ */
open class Filter : RealmObject(), RowRepresentable, Identifiable, Deletable, ImageDecorator { open class Filter : RealmObject(), RowRepresentable, Identifiable, Deletable, CountableUsage, ImageDecorator {
companion object { companion object {
@ -61,25 +60,20 @@ open class Filter : RealmObject(), RowRepresentable, Identifiable, Deletable, Im
// the queryWith name // the queryWith name
var name: String = "" var name: String = ""
get() {
if (field.isEmpty()) {
return this.query.defaultName
}
return field
}
// the number of use of the queryWith, override var useCount: Int = 0
// for MutableRealmInteger, see https://realm.io/docs/java/latest/#counters
val usageCount: MutableRealmInteger = MutableRealmInteger.valueOf(0)
var filterConditions: RealmList<FilterCondition> = RealmList() var filterConditions: RealmList<FilterCondition> = RealmList()
private set private set
private var filterableTypeOrdinal: Int? = null private var filterableTypeOrdinal: Int? = null
override val viewType: Int
get() = RowViewType.TITLE_VALUE_ACTION.ordinal
override val imageRes: Int?
get() = R.drawable.ic_outline_settings
override val imageTint: Int?
get() = R.color.green
override val imageClickable: Boolean?
get() = true
val filterableType: FilterableType val filterableType: FilterableType
get() { get() {
this.filterableTypeOrdinal?.let { this.filterableTypeOrdinal?.let {
@ -180,10 +174,10 @@ open class Filter : RealmObject(), RowRepresentable, Identifiable, Deletable, Im
} }
override fun isValidForDelete(context: Context, realm: Realm): Boolean { override fun isValidForDelete(context: Context, realm: Realm): Boolean {
return id != Preferences.getActiveFilterId(context) return true
} }
override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int { override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int {
return R.string.filter_currently_selected return R.string.relationship_error
} }
} }

@ -174,7 +174,7 @@
// } // }
// //
// fun createSessionSet(owner: Session) { // fun createSessionSet(owner: Session) {
// val set: SessionSet = SessionSet.newInstance(this.realm) // val set: SessionSet = SessionSet.newInstanceForResult(this.realm)
// set.timeFrame?.let { // set.timeFrame?.let {
// it.startDate = this.startDate // it.startDate = this.startDate
// it.endDate = this.endDate // it.endDate = this.endDate
@ -269,7 +269,7 @@
// sessionSets.deleteAllFromRealm() // sessionSets.deleteAllFromRealm()
// //
// // Create a new sets // // Create a new sets
// val set: SessionSet = SessionSet.newInstance(this.realm) // val set: SessionSet = SessionSet.newInstanceForResult(this.realm)
// set.timeFrame?.let { // set.timeFrame?.let {
// it.setDate(startDate, endDate) // it.setDate(startDate, endDate)
// } ?: run { // } ?: run {

@ -13,6 +13,8 @@ import net.pokeranalytics.android.BuildConfig
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Currency import net.pokeranalytics.android.model.realm.Currency
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.activity.components.RequestCode
import net.pokeranalytics.android.ui.activity.components.ResultCode
import net.pokeranalytics.android.ui.adapter.HomePagerAdapter import net.pokeranalytics.android.ui.adapter.HomePagerAdapter
import net.pokeranalytics.android.ui.extensions.showAlertDialog import net.pokeranalytics.android.ui.extensions.showAlertDialog
import net.pokeranalytics.android.util.billing.AppGuard import net.pokeranalytics.android.util.billing.AppGuard
@ -96,10 +98,20 @@ class HomeActivity : PokerAnalyticsActivity() {
Timber.d("Intent ${intent.action} unmanaged") Timber.d("Intent ${intent.action} unmanaged")
} }
} }
}
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
RequestCode.IMPORT.value -> {
if (resultCode == ResultCode.IMPORT_UNRECOGNIZED_FORMAT.value) {
showAlertDialog(context = this, message = R.string.unknown_import_format_popup_message)
}
}
}
} }
private fun observeRealmObjects() { private fun observeRealmObjects() {
@ -154,10 +166,10 @@ class HomeActivity : PokerAnalyticsActivity() {
// Import // Import
fun requestImportConfirmation(uri: Uri) { private fun requestImportConfirmation(uri: Uri) {
showAlertDialog(this, R.string.import_confirmation, showCancelButton = true, positiveAction = { showAlertDialog(context = this, title = R.string.import_confirmation, showCancelButton = true, positiveAction = {
ImportActivity.newInstance(this, uri) ImportActivity.newInstanceForResult(this, uri)
}) })
} }

@ -4,9 +4,11 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import io.realm.Realm import io.realm.Realm
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.activity.components.RequestCode
import net.pokeranalytics.android.ui.fragment.ImportFragment import net.pokeranalytics.android.ui.fragment.ImportFragment
import timber.log.Timber import timber.log.Timber
@ -23,8 +25,8 @@ class ImportActivity : PokerAnalyticsActivity() {
/** /**
* Create a new instance for result * Create a new instance for result
*/ */
fun newInstance(context: Context, uri: Uri) { fun newInstanceForResult(context: FragmentActivity, uri: Uri) {
context.startActivity(getIntent(context, uri)) context.startActivityForResult(getIntent(context, uri), RequestCode.IMPORT.value)
} }
private fun getIntent(context: Context, uri: Uri): Intent { private fun getIntent(context: Context, uri: Uri): Intent {
@ -41,6 +43,7 @@ class ImportActivity : PokerAnalyticsActivity() {
setContentView(R.layout.activity_import) setContentView(R.layout.activity_import)
initUI() initUI()
} }
override fun onStop() { override fun onStop() {

@ -9,6 +9,7 @@ import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.ui.activity.components.ReportActivity import net.pokeranalytics.android.ui.activity.components.ReportActivity
import net.pokeranalytics.android.ui.activity.components.ReportParameters import net.pokeranalytics.android.ui.activity.components.ReportParameters
import net.pokeranalytics.android.ui.activity.components.RequestCode
import net.pokeranalytics.android.ui.fragment.report.ProgressReportFragment import net.pokeranalytics.android.ui.fragment.report.ProgressReportFragment
class ProgressReportActivity : ReportActivity() { class ProgressReportActivity : ReportActivity() {
@ -29,7 +30,7 @@ class ProgressReportActivity : ReportActivity() {
fun newInstanceForResult(fragment: Fragment, report: Report, title: String, stat: Stat? = null, displayAggregationChoices: Boolean = true) { fun newInstanceForResult(fragment: Fragment, report: Report, title: String, stat: Stat? = null, displayAggregationChoices: Boolean = true) {
parameters = ReportParameters(report, title, stat, showAggregationChoices = displayAggregationChoices) parameters = ReportParameters(report, title, stat, showAggregationChoices = displayAggregationChoices)
val intent = Intent(fragment.context, ProgressReportActivity::class.java) val intent = Intent(fragment.context, ProgressReportActivity::class.java)
fragment.startActivityForResult(intent, DEFAULT_REQUEST_CODE) fragment.startActivityForResult(intent, RequestCode.DEFAULT.value)
} }
} }

@ -7,13 +7,10 @@ import androidx.fragment.app.Fragment
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.activity.components.RequestCode
class ReportCreationActivity : PokerAnalyticsActivity() { class ReportCreationActivity : PokerAnalyticsActivity() {
enum class RequestCode {
NEW_REPORT
}
companion object { companion object {
var options: Calculator.Options? = null var options: Calculator.Options? = null

@ -0,0 +1,11 @@
package net.pokeranalytics.android.ui.activity.components
enum class RequestCode(var value: Int) {
DEFAULT(1),
NEW_REPORT(800),
IMPORT(900)
}
enum class ResultCode(var value: Int) {
IMPORT_UNRECOGNIZED_FORMAT(901)
}

@ -12,8 +12,6 @@ abstract class ReportActivity : PokerAnalyticsActivity() {
companion object { companion object {
const val DEFAULT_REQUEST_CODE = 999
// Unparcel fails when setting a custom Parcelable object on Entry so we use a static reference to passe objects // Unparcel fails when setting a custom Parcelable object on Entry so we use a static reference to passe objects
var parameters: ReportParameters? = null var parameters: ReportParameters? = null
@ -31,7 +29,7 @@ abstract class ReportActivity : PokerAnalyticsActivity() {
val options = report.options val options = report.options
this.parameters = ReportParameters(report, reportTitle, stat) this.parameters = ReportParameters(report, reportTitle, stat)
val intent = Intent(fragment.requireContext(), options.display.activityClass) val intent = Intent(fragment.requireContext(), options.display.activityClass)
fragment.startActivityForResult(intent, DEFAULT_REQUEST_CODE) fragment.startActivityForResult(intent, RequestCode.DEFAULT.value)
} }
} }

@ -16,10 +16,10 @@ import androidx.core.content.FileProvider
import androidx.core.view.isVisible import androidx.core.view.isVisible
import net.pokeranalytics.android.BuildConfig import net.pokeranalytics.android.BuildConfig
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.util.DeviceUtils import net.pokeranalytics.android.util.DeviceUtils
import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.util.URL import net.pokeranalytics.android.util.URL
import net.pokeranalytics.android.util.billing.AppGuard import net.pokeranalytics.android.util.billing.AppGuard
import java.io.File import java.io.File
@ -114,7 +114,7 @@ fun PokerAnalyticsFragment.showAlertDialog(title: Int? = null, message: Int? = n
* Create and show an alert dialog * Create and show an alert dialog
*/ */
fun showAlertDialog( fun showAlertDialog(
context: Context, title: Int? = null, message: Int? = null, showCancelButton: Boolean = false, context: Context, title: Int? = null, message: Int? = null, cancelButtonTitle: Int? = null, showCancelButton: Boolean = false,
positiveAction: (() -> Unit)? = null, negativeAction: (() -> Unit)? = null positiveAction: (() -> Unit)? = null, negativeAction: (() -> Unit)? = null
) { ) {
val builder = AlertDialog.Builder(context) val builder = AlertDialog.Builder(context)
@ -127,7 +127,12 @@ fun showAlertDialog(
builder.setPositiveButton(net.pokeranalytics.android.R.string.ok) { _, _ -> builder.setPositiveButton(net.pokeranalytics.android.R.string.ok) { _, _ ->
positiveAction?.invoke() positiveAction?.invoke()
} }
if (showCancelButton) {
if (cancelButtonTitle != null) {
builder.setNegativeButton(cancelButtonTitle) { _, _ ->
negativeAction?.invoke()
}
} else if (showCancelButton) {
builder.setNegativeButton(R.string.cancel) { _, _ -> builder.setNegativeButton(R.string.cancel) { _, _ ->
negativeAction?.invoke() negativeAction?.invoke()
} }

@ -107,18 +107,11 @@ class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource
when (this.dataType) { when (this.dataType) {
LiveData.FILTER -> { LiveData.FILTER -> {
if (fromAction) {
// Open filter params
val filter = row as Filter
FiltersActivity.newInstanceForResult(fragment = this, filterId = filter.id, currentFilterable = filter.filterableType)
} else {
// Select filter
val intent = Intent() val intent = Intent()
intent.putExtra(FiltersActivity.IntentKey.FILTER_ID.keyName, (row as Filter).id) intent.putExtra(FiltersActivity.IntentKey.FILTER_ID.keyName, (row as Filter).id)
activity?.setResult(Activity.RESULT_OK, intent) activity?.setResult(Activity.RESULT_OK, intent)
activity?.finish() activity?.finish()
} }
}
else -> { else -> {
val identifier = (row as Identifiable).id val identifier = (row as Identifiable).id
EditableDataActivity.newInstanceForResult(this, this.dataType, identifier, REQUEST_CODE_DETAILS) EditableDataActivity.newInstanceForResult(this, this.dataType, identifier, REQUEST_CODE_DETAILS)

@ -195,14 +195,16 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
} }
// Sessions // Sessions
this.realmSessions = sessionFilter?.results() ?: run { getRealm().where<Session>().findAll() }.sort("startDate", Sort.DESCENDING) this.realmSessions = sessionFilter?.results() ?: run { getRealm().where<Session>().findAll() }
this.realmSessions = this.realmSessions.sort("startDate", Sort.DESCENDING)
this.realmSessions.addChangeListener { _, _ -> this.realmSessions.addChangeListener { _, _ ->
this.feedSessionAdapter.refreshData() this.feedSessionAdapter.refreshData()
this.feedSessionAdapter.notifyDataSetChanged() this.feedSessionAdapter.notifyDataSetChanged()
} }
val pendingSessions = sessionFilter?.let { getRealm().where<Session>().alwaysFalse().findAll() } ?: run { getRealm().where<Session>().isNull("year").isNull("month").findAll().sort("startDate", Sort.DESCENDING) } val pendingSessions = sessionFilter?.let { getRealm().where<Session>().alwaysFalse().findAll() } ?: run { getRealm().where<Session>().isNull("year").isNull("month").findAll().sort("startDate", Sort.DESCENDING) }
val distinctDateSessions = sessionFilter?.results("year", "month") ?: run { getRealm().where<Session>().distinct("year", "month").findAll() }.sort("startDate", Sort.DESCENDING) var distinctDateSessions = sessionFilter?.results("year", "month") ?: run { getRealm().where<Session>().distinct("year", "month").findAll() }
distinctDateSessions = distinctDateSessions.sort("startDate", Sort.DESCENDING)
this.feedSessionAdapter = FeedSessionRowRepresentableAdapter(this, realmSessions, pendingSessions, distinctDateSessions) this.feedSessionAdapter = FeedSessionRowRepresentableAdapter(this, realmSessions, pendingSessions, distinctDateSessions)
} }
@ -216,13 +218,15 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
} }
// Transactions // Transactions
this.realmTransactions = transactionFilter?.results() ?: run { getRealm().where<Transaction>().findAll()}.sort("date", Sort.DESCENDING) this.realmTransactions = transactionFilter?.results() ?: run { getRealm().where<Transaction>().findAll()}
this.realmTransactions = this.realmTransactions.sort("date", Sort.DESCENDING)
this.realmTransactions.addChangeListener { _, _ -> this.realmTransactions.addChangeListener { _, _ ->
this.feedTransactionAdapter.refreshData() this.feedTransactionAdapter.refreshData()
this.feedTransactionAdapter.notifyDataSetChanged() this.feedTransactionAdapter.notifyDataSetChanged()
} }
val distinctDateTransactions = transactionFilter?.results("year", "month") ?: run { getRealm().where<Transaction>().distinct("year", "month").findAll() }.sort("date", Sort.DESCENDING) var distinctDateTransactions = transactionFilter?.results("year", "month") ?: run { getRealm().where<Transaction>().distinct("year", "month").findAll() }
distinctDateTransactions = distinctDateTransactions.sort("date", Sort.DESCENDING)
this.feedTransactionAdapter = FeedTransactionRowRepresentableAdapter(this, realmTransactions, distinctDateTransactions) this.feedTransactionAdapter = FeedTransactionRowRepresentableAdapter(this, realmTransactions, distinctDateTransactions)
} }
@ -235,7 +239,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
// val sessionCount = this.feedSessionAdapter.realmResults.size // val sessionCount = this.feedSessionAdapter.realmResults.size
// if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG // if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG
// Toast.makeText(context, "Please subscribe!", Toast.LENGTH_LONG).show() // Toast.makeText(context, "Please subscribe!", Toast.LENGTH_LONG).show()
// BillingActivity.newInstance(requireContext()) // BillingActivity.newInstanceForResult(requireContext())
// return // return
// } // }

@ -176,7 +176,7 @@ open class FiltersFragment : RealmFragment(), StaticRowRepresentableDataSource,
isUpdating = true isUpdating = true
} ?: run { } ?: run {
realm.beginTransaction() realm.beginTransaction()
currentFilter = Filter.newInstance(realm, this.filterableType.ordinal) //realm.copyFromRealm(Filter.newInstance(realm, this.filterableType.ordinal)) currentFilter = Filter.newInstance(realm, this.filterableType.ordinal) //realm.copyFromRealm(Filter.newInstanceForResult(realm, this.filterableType.ordinal))
realm.commitTransaction() realm.commitTransaction()
} }

@ -9,8 +9,10 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.components.ResultCode
import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.util.csv.CSVImporter import net.pokeranalytics.android.util.csv.CSVImporter
import net.pokeranalytics.android.util.csv.ImportException
import timber.log.Timber import timber.log.Timber
import java.io.InputStream import java.io.InputStream
import java.util.* import java.util.*
@ -29,7 +31,6 @@ class ImportFragment : RealmFragment() {
} }
fun setData(inputStream: InputStream) { fun setData(inputStream: InputStream) {
Timber.d("> setData with IS...")
this.inputStream = inputStream this.inputStream = inputStream
} }
@ -41,28 +42,43 @@ class ImportFragment : RealmFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
Timber.d("> onViewCreated...")
this.startImport() this.startImport()
} }
fun startImport() { fun startImport() {
var shouldDismissActivity = false
GlobalScope.launch(coroutineContext) { GlobalScope.launch(coroutineContext) {
val test = GlobalScope.async { val test = GlobalScope.async {
val s = Date() val s = Date()
Timber.d(">>> Start Import...") Timber.d(">>> Start Import...")
try {
val csv = CSVImporter(inputStream) val csv = CSVImporter(inputStream)
csv.start() csv.start()
} catch (e: ImportException) {
shouldDismissActivity = true
}
val e = Date() val e = Date()
val duration = (e.time - s.time) / 1000.0 val duration = (e.time - s.time) / 1000.0
Timber.d(">>> Import ended in $duration seconds") Timber.d(">>> Import ended in $duration seconds")
} }
test.await() test.await()
if (shouldDismissActivity) {
activity?.let {
it.setResult(ResultCode.IMPORT_UNRECOGNIZED_FORMAT.value)
it.finish()
} }
}
}
} }
} }

@ -25,6 +25,7 @@ import net.pokeranalytics.android.model.realm.ReportSetup
import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.DataListActivity
import net.pokeranalytics.android.ui.activity.ReportCreationActivity import net.pokeranalytics.android.ui.activity.ReportCreationActivity
import net.pokeranalytics.android.ui.activity.components.ReportActivity import net.pokeranalytics.android.ui.activity.components.ReportActivity
import net.pokeranalytics.android.ui.activity.components.RequestCode
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
@ -38,7 +39,6 @@ import java.util.*
class ReportsFragment : DeletableItemFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { class ReportsFragment : DeletableItemFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate {
// private lateinit var dataListAdapter: RowRepresentableAdapter
private lateinit var reportSetups: RealmResults<ReportSetup> private lateinit var reportSetups: RealmResults<ReportSetup>
private var adapterRows = mutableListOf<RowRepresentable>() private var adapterRows = mutableListOf<RowRepresentable>()
@ -77,12 +77,12 @@ class ReportsFragment : DeletableItemFragment(), StaticRowRepresentableDataSourc
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
if (requestCode == ReportCreationActivity.RequestCode.NEW_REPORT.ordinal && resultCode == Activity.RESULT_OK) { if (requestCode == RequestCode.NEW_REPORT.ordinal && resultCode == Activity.RESULT_OK) {
ReportCreationActivity.options?.let { options -> ReportCreationActivity.options?.let { options ->
this.launchReportWithOptions(options, options.getName(requireContext())) this.launchReportWithOptions(options, options.getName(requireContext()))
} }
ReportCreationActivity.options = null ReportCreationActivity.options = null
} else if (requestCode == ReportActivity.DEFAULT_REQUEST_CODE && resultCode == Activity.RESULT_OK) { } else if (requestCode == RequestCode.DEFAULT.value && resultCode == Activity.RESULT_OK) {
val itemToDeleteId = data?.getStringExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName) val itemToDeleteId = data?.getStringExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName)
itemToDeleteId?.let { id -> itemToDeleteId?.let { id ->
GlobalScope.launch(Dispatchers.Main) { GlobalScope.launch(Dispatchers.Main) {

@ -217,7 +217,7 @@ open class ComposableTableReportFragment : RealmFragment(), StaticRowRepresentab
ReportActivity.newInstance(requireContext(), it, title, stat) ReportActivity.newInstance(requireContext(), it, title, stat)
// ProgressReportActivity.newInstance(requireContext(), stat, it, title = title) // ProgressReportActivity.newInstanceForResult(requireContext(), stat, it, title = title)
} }
} }
} }

@ -36,6 +36,18 @@ interface FilterHandler {
fun saveFilter(context: Context, filterId:String) { fun saveFilter(context: Context, filterId:String) {
Preferences.setActiveFilterId(filterId, context) Preferences.setActiveFilterId(filterId, context)
println("<<<< save filter")
val realm = Realm.getDefaultInstance()
realm.beginTransaction()
currentFilter(context, realm)?.let {
println("<<<< old ${it.useCount}")
it.useCount++
println("<<<< new ${it.useCount}")
}
realm.commitTransaction()
realm.close()
// Send broadcast // Send broadcast
val intent = Intent() val intent = Intent()
intent.action = INTENT_FILTER_UPDATE_FILTER_UI intent.action = INTENT_FILTER_UPDATE_FILTER_UI

@ -31,7 +31,7 @@ open class CSVImporter(istream: InputStream) {
/** /**
* The number of valid record to test for descriptor before throwing a File Format Exception * The number of valid record to test for descriptor before throwing a File Format Exception
*/ */
private val VALID_RECORD_ATTEMPTS_BEFORE_THROWING_EXCEPTION = 5 private val VALID_RECORD_ATTEMPTS_BEFORE_THROWING_EXCEPTION = 4
/** /**
* The path of the CSV file * The path of the CSV file
@ -85,9 +85,12 @@ open class CSVImporter(istream: InputStream) {
this.currentDescriptor = this.findDescriptor(record) this.currentDescriptor = this.findDescriptor(record)
if (this.currentDescriptor == null) { if (this.currentDescriptor == null) {
this.descriptorFindingAttempts++
if (record.size() > VALID_RECORD_COLUMNS && this.descriptorFindingAttempts > VALID_RECORD_ATTEMPTS_BEFORE_THROWING_EXCEPTION) { if (record.size() >= VALID_RECORD_COLUMNS) {
this.descriptorFindingAttempts++
}
if (this.descriptorFindingAttempts >= VALID_RECORD_ATTEMPTS_BEFORE_THROWING_EXCEPTION) {
realm.cancelTransaction()
throw ImportException("This type of file is not supported") throw ImportException("This type of file is not supported")
} }
} }
@ -110,6 +113,7 @@ open class CSVImporter(istream: InputStream) {
it.parse(realm, record) it.parse(realm, record)
} }
} ?: run { } ?: run {
realm.cancelTransaction()
throw IllegalStateException("CSVDescriptor should never be null here") throw IllegalStateException("CSVDescriptor should never be null here")
} }

@ -7,6 +7,7 @@ import io.realm.Sort
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.model.interfaces.CountableUsage import net.pokeranalytics.android.model.interfaces.CountableUsage
import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.TournamentFeature import net.pokeranalytics.android.model.realm.TournamentFeature
import net.pokeranalytics.android.model.realm.Transaction import net.pokeranalytics.android.model.realm.Transaction
@ -30,23 +31,29 @@ inline fun <reified T: NameManageable> Realm.getOrCreate(name: String) : T {
* Returns all entities of the [clazz] sorted with their default sorting * Returns all entities of the [clazz] sorted with their default sorting
*/ */
fun < T : RealmModel> Realm.sorted(clazz: Class<T>) : RealmResults<T> { fun < T : RealmModel> Realm.sorted(clazz: Class<T>) : RealmResults<T> {
val items = this.where(clazz).findAll()
var sortField = arrayOf("name")
var resultSort = arrayOf(Sort.ASCENDING)
if (clazz is CountableUsage) { when (items.firstOrNull()) {
this.updateUsageCount(clazz) is Transaction -> {
println("<<<< is transaction")
sortField = arrayOf("date")
resultSort = arrayOf(Sort.DESCENDING)
} }
is Filter -> {
val sortField = when (clazz) { println("<<<< is filter")
is CountableUsage -> "useCount" sortField = arrayOf("useCount", "name")
is Transaction -> "date" resultSort = arrayOf(Sort.DESCENDING, Sort.ASCENDING)
else -> "name"
} }
val resultSort = when (clazz) { is CountableUsage -> {
is CountableUsage -> Sort.DESCENDING println("<<<< is countable")
is Transaction -> Sort.DESCENDING this.updateUsageCount(clazz)
else -> Sort.ASCENDING sortField = arrayOf("useCount")
resultSort = arrayOf(Sort.DESCENDING)
} }
}
return this.where(clazz).findAll().sort(sortField, resultSort) return items.sort(sortField, resultSort)
} }
/** /**

Loading…
Cancel
Save