diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt index 223b1af4..4801aed6 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt @@ -11,8 +11,10 @@ import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.filter import net.pokeranalytics.android.model.realm.ComputableResult import net.pokeranalytics.android.model.realm.Filter -import net.pokeranalytics.android.model.realm.ReportSetup import net.pokeranalytics.android.model.realm.SessionSet +import net.pokeranalytics.android.ui.activity.ComparisonReportActivity +import net.pokeranalytics.android.ui.activity.ProgressReportActivity +import net.pokeranalytics.android.ui.activity.TableReportActivity import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.util.extensions.startOfDay import java.util.* @@ -35,7 +37,8 @@ class Calculator { query: Query = Query(), filter: Filter? = null, var aggregationType: AggregationType? = null, - var userGenerated: Boolean = false + var userGenerated: Boolean = false, + var reportSetupId: String? = null ) { var evolutionValues: EvolutionValues = evolutionValues @@ -47,17 +50,17 @@ class Calculator { } private var _query: Query = query - private var _filter: Filter? = filter + var filter: Filter? = filter init { - if (!this._query.conditions.isEmpty() && this._filter != null) { + if (!this._query.conditions.isEmpty() && this.filter != null) { throw IllegalStateException("Can't specify a query with conditions AND a filter") } } val query: Query get() { - this._filter?.let { + this.filter?.let { return it.query } return this._query @@ -84,6 +87,19 @@ class Calculator { } } + val activityClass: Class<*> + get() { + return when (this) { + TABLE -> TableReportActivity::class.java + PROGRESS -> ProgressReportActivity::class.java + COMPARISON -> ComparisonReportActivity::class.java + else -> throw IllegalStateException("undefined activity for report display") +// MAP -> R.string.map +// POLYNOMIAL -> null + + } + } + } /** @@ -134,21 +150,21 @@ class Calculator { } } - fun reportSetup(name: String): ReportSetup { - - val rs = ReportSetup() - rs.name = name - rs.display = this.display.ordinal - this.stats.forEach { - rs.statIds.add(it.uniqueIdentifier) - } - this.criterias.forEach { - rs.criteriaIds.add(it.uniqueIdentifier) - } - rs.filter = this._filter - - return rs - } +// fun reportSetup(name: String): ReportSetup { +// +// val rs = ReportSetup() +// rs.name = name +// rs.display = this.display.ordinal +// this.stats.forEach { +// rs.statIds.add(it.uniqueIdentifier) +// } +// this.criterias.forEach { +// rs.criteriaIds.add(it.uniqueIdentifier) +// } +// rs.filter = this.filter +// +// return rs +// } /** * Returns some default name @@ -172,8 +188,11 @@ class Calculator { stats: List? = null ): Report { - val options = Options(evolutionValues = Options.EvolutionValues.STANDARD, aggregationType = aggregationType) - options.stats = listOf(stat) + val options = Options(display = Options.Display.PROGRESS, + evolutionValues = Options.EvolutionValues.STANDARD, + stats = listOf(stat), + aggregationType = aggregationType) + if (aggregationType == AggregationType.DURATION) { options.evolutionValues = Options.EvolutionValues.TIMED } 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 5a556290..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 @@ -24,76 +20,10 @@ enum class LiveData : Localizable { TRANSACTION, TRANSACTION_TYPE, FILTER, - CUSTOM_FIELD; + 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 @@ -105,15 +35,12 @@ enum class LiveData : Localizable { TRANSACTION_TYPE -> TransactionType::class.java FILTER -> Filter::class.java CUSTOM_FIELD -> CustomField::class.java + REPORT_SETUP -> ReportSetup::class.java } } - 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 { @@ -121,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 { @@ -148,6 +75,7 @@ enum class LiveData : Localizable { TRANSACTION_TYPE -> R.string.operation_types FILTER -> R.string.filter CUSTOM_FIELD -> R.string.custom_fields + REPORT_SETUP -> R.string.custom } } 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 70478fd9..1c72398b 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.interfaces.FilterableType import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow @@ -17,7 +18,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 { @@ -49,7 +50,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/ReportSetup.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/ReportSetup.kt index b63a205c..82b996e8 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/ReportSetup.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/ReportSetup.kt @@ -1,6 +1,7 @@ package net.pokeranalytics.android.model.realm import android.content.Context +import io.realm.Realm import io.realm.RealmList import io.realm.RealmObject import io.realm.annotations.Ignore @@ -8,15 +9,17 @@ import io.realm.annotations.PrimaryKey import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.model.Criteria +import net.pokeranalytics.android.model.interfaces.Deletable +import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType import java.util.* -open class ReportSetup : RealmObject(), RowRepresentable { +open class ReportSetup : RealmObject(), RowRepresentable, Deletable { @PrimaryKey - var id = UUID.randomUUID().toString() + override var id = UUID.randomUUID().toString() // The name of the report var name: String = "" @@ -60,8 +63,19 @@ open class ReportSetup : RealmObject(), RowRepresentable { stats = stats, criterias = criteria, filter = this.filter, - userGenerated = true + userGenerated = true, + reportSetupId = this.id ) } + // Deletable + + override fun isValidForDelete(realm: Realm): Boolean { + return true + } + + override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + } 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 54be448f..2b938ee2 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 @@ -697,7 +697,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat // Add custom fields realm?.let { rows.add(SeparatorRow()) - rows.addAll(LiveData.CUSTOM_FIELD.itemsArray(it) as ArrayList) + rows.addAll(it.sorted()) } return rows @@ -778,32 +778,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/ComparisonReportActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/ComparisonReportActivity.kt index 8d776327..8dda891b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/ComparisonReportActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/ComparisonReportActivity.kt @@ -1,35 +1,12 @@ package net.pokeranalytics.android.ui.activity -import android.content.Context -import android.content.Intent import android.os.Bundle import net.pokeranalytics.android.R -import net.pokeranalytics.android.calculus.Report -import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity +import net.pokeranalytics.android.ui.activity.components.ReportActivity import net.pokeranalytics.android.ui.fragment.report.ComparisonReportFragment - -class ComparisonReportActivity : PokerAnalyticsActivity() { - - companion object { - - // Unparcel fails when setting a custom Parcelable object on Entry so we use a static reference to passe objects - private var report: Report? = null - private var reportTitle: String = "" - - /** - * Default constructor - */ - fun newInstance(context: Context, report: Report, reportTitle: String) { - //parameters = GraphParameters(stat, group, report) - this.report = report - this.reportTitle = reportTitle - val intent = Intent(context, ComparisonReportActivity::class.java) - context.startActivity(intent) - } - - } +class ComparisonReportActivity : ReportActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -42,14 +19,18 @@ class ComparisonReportActivity : PokerAnalyticsActivity() { */ private fun initUI() { - report?.let { + parameters?.let { + + val report = it.report + val title = it.title + val fragmentTransaction = supportFragmentManager.beginTransaction() - val reportDetailsFragment = ComparisonReportFragment.newInstance(it, reportTitle) + val reportDetailsFragment = ComparisonReportFragment.newInstance(report, title) fragmentTransaction.add(R.id.reportDetailsContainer, reportDetailsFragment) fragmentTransaction.commit() - - report = null } + parameters = null + } } 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/activity/ProgressReportActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/ProgressReportActivity.kt index dd61d2fe..d11984a4 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/ProgressReportActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/ProgressReportActivity.kt @@ -3,33 +3,35 @@ package net.pokeranalytics.android.ui.activity import android.content.Context import android.content.Intent import android.os.Bundle +import androidx.fragment.app.Fragment import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.Report import net.pokeranalytics.android.calculus.Stat -import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity +import net.pokeranalytics.android.ui.activity.components.ReportActivity +import net.pokeranalytics.android.ui.activity.components.ReportParameters import net.pokeranalytics.android.ui.fragment.report.ProgressReportFragment - -class StatisticsDetailsParameters(var stat: Stat, var report: Report, var title: String? = null) - -class ProgressReportActivity : PokerAnalyticsActivity() { +class ProgressReportActivity : ReportActivity() { companion object { // Unparcel fails when setting a custom Parcelable object on Entry so we use a static reference to passe objects - private var parameters: StatisticsDetailsParameters? = null - private var displayAggregationChoices: Boolean = true /** * Default constructor */ - fun newInstance(context: Context, stat: Stat, report: Report, displayAggregationChoices: Boolean = true, title: String? = null) { - parameters = StatisticsDetailsParameters(stat, report, title) - this.displayAggregationChoices = displayAggregationChoices + fun newInstance(context: Context, report: Report, title: String, stat: Stat? = null, displayAggregationChoices: Boolean = true) { + parameters = ReportParameters(report, title, stat, showAggregationChoices = displayAggregationChoices) val intent = Intent(context, ProgressReportActivity::class.java) context.startActivity(intent) } + fun newInstanceForResult(fragment: Fragment, report: Report, title: String, stat: Stat? = null, displayAggregationChoices: Boolean = true) { + parameters = ReportParameters(report, title, stat, showAggregationChoices = displayAggregationChoices) + val intent = Intent(fragment.context, ProgressReportActivity::class.java) + fragment.startActivityForResult(intent, DEFAULT_REQUEST_CODE) + } + } override fun onCreate(savedInstanceState: Bundle?) { @@ -49,7 +51,9 @@ class ProgressReportActivity : PokerAnalyticsActivity() { fragmentTransaction.commit() parameters?.let { - statisticDetailsFragment.setData(it.stat, it.report, displayAggregationChoices, it.title) + val report = it.report + val stat = it.stat ?: report.options.stats.first() + statisticDetailsFragment.setData(report, stat, it.showAggregationChoices, it.title) parameters = null } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/TableReportActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/TableReportActivity.kt index adc357a7..96bc4ddd 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/TableReportActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/TableReportActivity.kt @@ -1,32 +1,11 @@ package net.pokeranalytics.android.ui.activity -import android.content.Context -import android.content.Intent import android.os.Bundle import net.pokeranalytics.android.R -import net.pokeranalytics.android.calculus.Report -import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity +import net.pokeranalytics.android.ui.activity.components.ReportActivity import net.pokeranalytics.android.ui.fragment.report.TableReportFragment -class TableReportActivity : PokerAnalyticsActivity() { - - companion object { - - // Unparcel fails when setting a custom Parcelable object on Entry so we use a static reference to passe objects - private var report: Report? = null - private var reportTitle: String = "" - - /** - * Default constructor - */ - fun newInstance(context: Context, report: Report, reportTitle: String) { - this.report = report - this.reportTitle = reportTitle - val intent = Intent(context, TableReportActivity::class.java) - context.startActivity(intent) - } - - } +class TableReportActivity : ReportActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -39,11 +18,18 @@ class TableReportActivity : PokerAnalyticsActivity() { */ private fun initUI() { - val fragmentTransaction = supportFragmentManager.beginTransaction() - val fragment = TableReportFragment.newInstance(report, reportTitle) - fragmentTransaction.add(R.id.reportDetailsContainer, fragment) - fragmentTransaction.commit() - report = null + parameters?.let { + + val report = it.report + val title = it.title + + val fragmentTransaction = supportFragmentManager.beginTransaction() + val fragment = TableReportFragment.newInstance(report, title) + fragmentTransaction.add(R.id.reportDetailsContainer, fragment) + fragmentTransaction.commit() + } + parameters = null + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/components/ReportActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/components/ReportActivity.kt new file mode 100644 index 00000000..6d2ea1be --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/components/ReportActivity.kt @@ -0,0 +1,39 @@ +package net.pokeranalytics.android.ui.activity.components + +import android.content.Context +import android.content.Intent +import androidx.fragment.app.Fragment +import net.pokeranalytics.android.calculus.Report +import net.pokeranalytics.android.calculus.Stat + +class ReportParameters(var report: Report, var title: String, var stat: Stat? = null, var showAggregationChoices: Boolean = true) + +abstract class ReportActivity : PokerAnalyticsActivity() { + + 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 + var parameters: ReportParameters? = null + + /** + * Default constructor + */ + fun newInstance(context: Context, report: Report, reportTitle: String, stat: Stat? = null) { + val options = report.options + this.parameters = ReportParameters(report, reportTitle, stat) + val intent = Intent(context, options.display.activityClass) + context.startActivity(intent) + } + + fun newInstanceForResult(fragment: Fragment, report: Report, reportTitle: String, stat: Stat? = null) { + val options = report.options + this.parameters = ReportParameters(report, reportTitle, stat) + val intent = Intent(fragment.requireContext(), options.display.activityClass) + fragment.startActivityForResult(intent, DEFAULT_REQUEST_CODE) + } + + } + +} \ No newline at end of file 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 a0b1479f..fc62cded 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 @@ -161,7 +161,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 26a9d1a6..8fb695cc 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 @@ -28,6 +28,7 @@ import net.pokeranalytics.android.ui.activity.BankrollDetailsActivity import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.EditableDataActivity import net.pokeranalytics.android.ui.activity.GraphActivity +import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource @@ -36,6 +37,8 @@ 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 net.pokeranalytics.android.util.sorted import timber.log.Timber import java.util.* import kotlin.collections.ArrayList @@ -66,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? { @@ -83,13 +92,14 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == REQUEST_CODE_DETAILS && resultCode == Activity.RESULT_OK) { - val needToDeleteItem = data?.getBooleanExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName, false) ?: false - if (needToDeleteItem) { + val itemToDeleteId = data?.getStringExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName) + itemToDeleteId?.let { id -> GlobalScope.launch(Dispatchers.Main) { delay(300) - deleteItem(bankrollAdapter, LiveData.BANKROLL.items(getRealm()), lastItemClickedId) + deleteItem(dataListAdapter, bankrolls, id) } } + } else if (requestCode == REQUEST_CODE_CREATE && resultCode == Activity.RESULT_OK) { //TODO: Refresh bankrolls initData() @@ -126,6 +136,9 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour */ private fun initData() { + val realm = getRealm() + this.bankrolls = realm.sorted() + rows.clear() bankrollReportForRow.clear() @@ -150,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) @@ -165,7 +178,7 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour } if (!isDetached) { - bankrollAdapter.notifyDataSetChanged() + dataListAdapter.notifyDataSetChanged() } } } @@ -179,20 +192,18 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour setDisplayHomeAsUpEnabled(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) } } @@ -200,7 +211,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) { @@ -214,7 +225,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/CalendarDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarDetailsFragment.kt index 5512aa35..72b7bfc3 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarDetailsFragment.kt @@ -137,10 +137,12 @@ class CalendarDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { when (row) { is GraphRow -> { - row.report?.let { report -> - row.stat?.let { stat -> - ProgressReportActivity.newInstance(requireContext(), stat, report, false, row.title) - } + val report = row.report + val stat = row.stat + + if (report != null && stat != null) { + val title = row.title ?: stat.localizedTitle(requireContext()) + ProgressReportActivity.newInstance(requireContext(), report, title, stat, false) } } } 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 4854459b..ce942b54 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.adapter.LiveRowRepresentableDataSource @@ -28,6 +23,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 { @@ -35,20 +32,27 @@ 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 setToolbarTitle(this.dataType.localizedTitle(requireContext())) - this.dataType.let { - this.items = it.items(getRealm()) - } + + val realm = getRealm() + this.items = realm.sorted(this.identifiableClass) + } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -61,7 +65,6 @@ class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource initUI() } - /** * Init UI */ @@ -87,27 +90,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 needToDeleteItem = - data?.getBooleanExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName, false) ?: false - if (needToDeleteItem) { - GlobalScope.launch(Dispatchers.Main) { - delay(300) - deleteItem(dataListAdapter, items, lastItemClickedId) - } - } + EditableDataActivity.newInstance( + requireContext(), + dataType = this.dataType.ordinal, + primaryKey = null + ) } } @@ -130,21 +117,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 1cd27365..9702f0b9 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 @@ -105,7 +105,7 @@ class FeedFragment : RealmFragment(), RowRepresentableDelegate { 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 8ad564ff..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 @@ -13,21 +13,22 @@ 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.calculus.Calculator import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.model.Criteria 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.ComparisonReportActivity -import net.pokeranalytics.android.ui.activity.ProgressReportActivity +import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.ReportCreationActivity -import net.pokeranalytics.android.ui.activity.TableReportActivity +import net.pokeranalytics.android.ui.activity.components.ReportActivity import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource -import net.pokeranalytics.android.ui.fragment.components.RealmFragment +import net.pokeranalytics.android.ui.fragment.components.DeletableItemFragment import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable @@ -35,12 +36,16 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.ReportRow import timber.log.Timber import java.util.* -class ReportsFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { +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 { /** @@ -77,9 +82,17 @@ class ReportsFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRe this.launchReportWithOptions(options, options.getName(requireContext())) } ReportCreationActivity.options = null + } else if (requestCode == ReportActivity.DEFAULT_REQUEST_CODE && resultCode == Activity.RESULT_OK) { + val itemToDeleteId = data?.getStringExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName) + itemToDeleteId?.let { id -> + GlobalScope.launch(Dispatchers.Main) { + delay(300) + deleteItem(dataListAdapter, reportSetups, id) + } + } } - } + } // Business @@ -98,14 +111,14 @@ class ReportsFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRe */ 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 { @@ -116,14 +129,14 @@ class ReportsFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRe // 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? { @@ -185,21 +198,7 @@ class ReportsFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRe launch(Dispatchers.Main) { if (!isDetached) { hideLoader() - - when (options.display) { - Calculator.Options.Display.TABLE -> { - TableReportActivity.newInstance(requireContext(), report, reportName) - } - Calculator.Options.Display.PROGRESS -> { - ProgressReportActivity.newInstance(requireContext(), options.stats.first(), report) - } - Calculator.Options.Display.COMPARISON -> { - ComparisonReportActivity.newInstance(requireContext(), report, reportName) - } - else -> { - Timber.d("Report type not handled at the moment") - } - } + ReportActivity.newInstanceForResult(this@ReportsFragment, report, reportName) } } realm.close() 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 0cd9ffba..3a441d84 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 @@ -289,7 +289,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 69e2cfd6..0eeb818a 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,32 +1,47 @@ 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 androidx.coordinatorlayout.widget.CoordinatorLayout 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 itemHasBeenReInserted: Boolean = false private var lastDeletedItemPosition: Int = 0 - private var dataListAdapter: RowRepresentableAdapter? = null - private var coordinatorLayout: CoordinatorLayout? = 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.coordinatorLayout = view.findViewById(R.id.coordinatorLayout) + this.mainLayout = view.findViewById(R.id.mainLayout) } override fun onPause() { @@ -34,6 +49,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 @@ -41,7 +71,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 @@ -50,8 +80,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) { @@ -85,7 +115,7 @@ open class DeletableItemFragment : RealmFragment() { */ private fun showUndoSnackBar() { val message = String.format(getString(R.string.data_deleted)) - this.coordinatorLayout?.let { view -> + this.mainLayout?.let { view -> snackBar = Snackbar.make(view, message, Snackbar.LENGTH_INDEFINITE) snackBar?.setAction(R.string.cancel) { if (!itemHasBeenReInserted) { @@ -99,6 +129,8 @@ open class DeletableItemFragment : RealmFragment() { } } snackBar?.show() + } ?: run { + throw IllegalStateException("mainLayout is not defined") } } @@ -106,14 +138,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 8f38bf64..8f4449ea 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 @@ -82,7 +82,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() } @@ -122,38 +122,22 @@ open class BottomSheetFragment : BottomSheetDialogFragment() { } 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/BankrollDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/BankrollDataFragment.kt index fc1735fe..ee3d7b51 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/BankrollDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/BankrollDataFragment.kt @@ -157,11 +157,11 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS /** * Init data */ - private fun initData() { + override fun initData() { defaultCurrency = UserDefaults.currency - if (!isUpdating) { + if (!deleteButtonShouldAppear) { bankroll.currency = net.pokeranalytics.android.model.realm.Currency() bankroll.currency?.code = defaultCurrency.currencyCode bankroll.currency?.rate = 1.0 diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt index 65f0f9bb..abdaee0a 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt @@ -258,7 +258,7 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa updateUI() rowRepresentableAdapter.notifyDataSetChanged() - if (!isUpdating) { + if (!this.deleteButtonShouldAppear) { rowRepresentableForPosition(0)?.let { onRowSelected(0, it) } 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 new file mode 100644 index 00000000..47e3ea4a --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt @@ -0,0 +1,158 @@ +package net.pokeranalytics.android.ui.fragment.data + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import androidx.appcompat.app.AlertDialog +import io.realm.RealmModel +import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.ConfigurationException +import net.pokeranalytics.android.model.LiveData +import net.pokeranalytics.android.model.interfaces.Deletable +import net.pokeranalytics.android.model.interfaces.Savable +import net.pokeranalytics.android.model.interfaces.SaveValidityStatus +import net.pokeranalytics.android.ui.activity.DataListActivity +import net.pokeranalytics.android.ui.activity.EditableDataActivity +import net.pokeranalytics.android.ui.fragment.components.RealmFragment + +open class DataManagerFragment : RealmFragment() { + + lateinit var item: RealmModel + + lateinit var liveDataType: LiveData + protected var primaryKey: String? = null + + var deleteButtonShouldAppear = false + set(value) { + field = value + this.updateMenuUI() + } + + var saveButtonShouldAppear = true + set(value) { + field = value + this.updateMenuUI() + } + + protected var dataType: Int? = null + + private var editableMenu: Menu? = null + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initData() + } + + override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { + menu?.clear() + inflater?.inflate(R.menu.toolbar_editable_data, menu) + this.editableMenu = menu + updateMenuUI() + super.onCreateOptionsMenu(menu, inflater) + } + + /** + * Update menu UI + */ + private fun updateMenuUI() { + editableMenu?.findItem(R.id.delete)?.isVisible = this.deleteButtonShouldAppear + editableMenu?.findItem(R.id.save)?.isVisible = this.saveButtonShouldAppear + } + + override fun onOptionsItemSelected(item: MenuItem?): Boolean { + when (item!!.itemId) { + R.id.save -> saveData() + R.id.delete -> deleteData() + } + return true + } + + /** + * Init data + */ + protected open fun initData() { + + this.deleteButtonShouldAppear = this.primaryKey != null + this.item = this.liveDataType.updateOrCreate(this.getRealm(), primaryKey) + + } + + /** + * Save data + */ + protected open fun saveData() { + + val savable = this.item + when (savable) { + is Savable -> { + val status = savable.getSaveValidityStatus(realm = this.getRealm()) + when (status) { + SaveValidityStatus.VALID -> { + this.getRealm().executeTransaction { + val managedItem = it.copyToRealmOrUpdate(this.item) + if (managedItem is Savable) { + val uniqueIdentifier = (managedItem as Savable).id + finishActivityWithResult(uniqueIdentifier) + } + } + onDataSaved() + } + else -> { + val message = 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") + } + } + + } + + /** + * Delete data + */ + protected open fun deleteData() { + + val deletable = this.item as Deletable + val realm = this.getRealm() + + if (deletable.isValidForDelete(realm)) { + val intent = Intent() + intent.putExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName, deletable.id) + activity?.setResult(Activity.RESULT_OK, intent) + activity?.finish() + } else { + val status = deletable.getDeleteStatus(realm) + val message = deletable.getFailedDeleteMessage(status) + val builder = AlertDialog.Builder(requireContext()) + .setMessage(message) + .setNegativeButton(R.string.ok, null) + builder.show() + } + } + + /** + * Finish the activity with a result + */ + private fun finishActivityWithResult(uniqueIdentifier: String) { + val intent = Intent() + intent.putExtra(EditableDataActivity.IntentKey.DATA_TYPE.keyName, dataType) + intent.putExtra(EditableDataActivity.IntentKey.PRIMARY_KEY.keyName, uniqueIdentifier) + activity?.setResult(Activity.RESULT_OK, intent) + activity?.finish() + } + + open fun onDataSaved() {} + + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/EditableDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/EditableDataFragment.kt index 4cb5b474..fd04b1d1 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 @@ -1,41 +1,28 @@ package net.pokeranalytics.android.ui.fragment.data -import android.app.Activity.RESULT_OK -import android.content.Intent import android.os.Bundle -import android.view.* -import androidx.appcompat.app.AlertDialog +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 -import net.pokeranalytics.android.exceptions.ConfigurationException import net.pokeranalytics.android.model.LiveData -import net.pokeranalytics.android.model.interfaces.Deletable import net.pokeranalytics.android.model.interfaces.Editable -import net.pokeranalytics.android.model.interfaces.Savable -import net.pokeranalytics.android.model.interfaces.SaveValidityStatus -import net.pokeranalytics.android.ui.activity.DataListActivity -import net.pokeranalytics.android.ui.activity.EditableDataActivity +import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate -import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment import net.pokeranalytics.android.ui.view.RowRepresentable -open class EditableDataFragment : RealmFragment(), RowRepresentableDelegate { +open class EditableDataFragment : DataManagerFragment(), RowRepresentableDelegate { - lateinit var item: RealmObject - lateinit var liveDataType: LiveData lateinit var rowRepresentableAdapter: RowRepresentableAdapter - private var editableMenu: Menu? = null - private var dataType: Int? = null - private var primaryKey: String? = null - - var isUpdating = false var shouldOpenKeyboard = true override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -46,24 +33,15 @@ open class EditableDataFragment : RealmFragment(), RowRepresentableDelegate { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initUI() - initData() - } - - override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { - menu?.clear() - inflater?.inflate(R.menu.toolbar_editable_data, menu) - this.editableMenu = menu - updateMenuUI() - super.onCreateOptionsMenu(menu, inflater) } - - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item!!.itemId) { - R.id.save -> saveData() - R.id.delete -> deleteData() - } - return true + /** + * Set fragment data + */ + fun setData(dataType: Int, primaryKey: String?) { + this.dataType = dataType + this.liveDataType = LiveData.values()[dataType] + this.primaryKey = primaryKey } override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { @@ -85,6 +63,16 @@ open class EditableDataFragment : RealmFragment(), RowRepresentableDelegate { setDisplayHomeAsUpEnabled(true) + val proxyItem: RealmModel? = this.liveDataType.getData(this.getRealm(), primaryKey) + proxyItem?.let { + //TODO: Localize + this.appBar.toolbar.title = "Update ${this.liveDataType.localizedTitle(requireContext()).toLowerCase().capitalize()}" + deleteButtonShouldAppear = true + } ?: run { + //TODO: Localize + this.appBar.toolbar.title = this.liveDataType.newEntityLocalizedTitle(requireContext()) + } + val viewManager = LinearLayoutManager(requireContext()) recyclerView.apply { setHasFixedSize(true) @@ -99,126 +87,20 @@ open class EditableDataFragment : RealmFragment(), RowRepresentableDelegate { return this.item as RowRepresentableDataSource } - /** - * Init data - */ - private fun initData() { - if (this.dataType != null) { - val proxyItem: RealmObject? = this.liveDataType.getData(this.getRealm(), primaryKey) - proxyItem?.let { - //TODO: Localize - //this.appBar.toolbar.title = "Update ${this.liveDataType.localizedTitle(requireContext()).toLowerCase().capitalize()}" - setToolbarTitle("Update ${this.liveDataType.localizedTitle(requireContext()).toLowerCase().capitalize()}") - isUpdating = true - } ?: run { - //TODO: Localize - //this.appBar.toolbar.title = this.liveDataType.newEntityLocalizedTitle(requireContext()) - setToolbarTitle(this.liveDataType.newEntityLocalizedTitle(requireContext())) - } - this.item = this.liveDataType.updateOrCreate(this.getRealm(), primaryKey) - - val dataSource = getDataSource() - this.rowRepresentableAdapter = RowRepresentableAdapter(getDataSource(), this) - this.rowRepresentableAdapter.setHasStableIds(true) - this.recyclerView.adapter = rowRepresentableAdapter - - // When creating an object, open automatically the keyboard for the first row - if (!isUpdating && shouldOpenKeyboard) { - val row = dataSource.adapterRows()?.firstOrNull() - row?.let { - onRowSelected(0, it) - } - } - } - } + override fun initData() { + super.initData() - /** - * Update menu UI - */ - private fun updateMenuUI() { - editableMenu?.findItem(R.id.delete)?.isVisible = isUpdating - editableMenu?.findItem(R.id.save)?.isVisible = true - } + val dataSource = getDataSource() + this.rowRepresentableAdapter = RowRepresentableAdapter(getDataSource(), this) + this.recyclerView.adapter = rowRepresentableAdapter - /** - * Save data - */ - fun saveData() { - - val savable = this.item - when (savable) { - is Savable -> { - val status = savable.getSaveValidityStatus(realm = this.getRealm()) - when (status) { - SaveValidityStatus.VALID -> { - this.getRealm().executeTransaction { - val managedItem = it.copyToRealmOrUpdate(this.item) - if (managedItem is Savable) { - val uniqueIdentifier = (managedItem as Savable).id - finishActivityWithResult(uniqueIdentifier) - } - } - onDataSaved() - } - else -> { - val message = 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") + // When creating an object, open automatically the keyboard for the first row + if (!deleteButtonShouldAppear && shouldOpenKeyboard) { + val row = dataSource.adapterRows()?.firstOrNull() + row?.let { + onRowSelected(0, it) } } - - } - - /** - * Delete data - */ - private fun deleteData() { - - val deletable = this.item as Deletable - val realm = this.getRealm() - - if (deletable.isValidForDelete(realm)) { - val intent = Intent() - intent.putExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName, true) - activity?.setResult(RESULT_OK, intent) - activity?.finish() - } else { - val status = deletable.getDeleteStatus(realm) - val message = deletable.getFailedDeleteMessage(status) - val builder = AlertDialog.Builder(requireContext()) - .setMessage(message) - .setNegativeButton(R.string.ok, null) - builder.show() - } - } - - /** - * Finish the activity with a result - */ - private fun finishActivityWithResult(uniqueIdentifier: String) { - val intent = Intent() - intent.putExtra(EditableDataActivity.IntentKey.DATA_TYPE.keyName, dataType) - intent.putExtra(EditableDataActivity.IntentKey.PRIMARY_KEY.keyName, uniqueIdentifier) - activity?.setResult(RESULT_OK, intent) - activity?.finish() } - /** - * Set fragment data - */ - fun setData(dataType: Int, primaryKey: String?) { - this.dataType = dataType - this.liveDataType = LiveData.values()[dataType] - this.primaryKey = primaryKey - } - - open fun onDataSaved() {} - } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/LocationDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/LocationDataFragment.kt index 06ca3d11..34853369 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/LocationDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/LocationDataFragment.kt @@ -40,7 +40,7 @@ class LocationDataFragment : EditableDataFragment(), StaticRowRepresentableDataS shouldOpenKeyboard = false locationActivated = parentActivity?.hasLocationPermissionGranted() ?: false - if (isUpdating) { + if (deleteButtonShouldAppear) { // If we update a location, we set the switch to the correct value locationActivated = location.latitude != null && location.longitude != null 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/ui/fragment/report/AbstractReportFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/AbstractReportFragment.kt index 0051c6f6..0b3b62a7 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/AbstractReportFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/AbstractReportFragment.kt @@ -1,53 +1,110 @@ package net.pokeranalytics.android.ui.fragment.report -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem +import android.os.Bundle +import android.view.View +import android.widget.EditText +import androidx.appcompat.app.AlertDialog +import kotlinx.android.synthetic.main.fragment_progress_report.* import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.Report -import net.pokeranalytics.android.ui.fragment.components.RealmFragment +import net.pokeranalytics.android.model.LiveData +import net.pokeranalytics.android.model.realm.ReportSetup +import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity +import net.pokeranalytics.android.ui.fragment.data.DataManagerFragment -abstract class AbstractReportFragment : RealmFragment() { +abstract class AbstractReportFragment : DataManagerFragment() { - protected lateinit var selectedReport: Report + private lateinit var _selectedReport: Report + + val selectedReport: Report + get() { + return this._selectedReport + } + + fun setReport(report: Report) { + this._selectedReport = report + this.primaryKey = report.options.reportSetupId + } protected var reportTitle: String? = null - private var editableMenu: Menu? = null + protected lateinit var parentActivity: PokerAnalyticsActivity - override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { - menu?.clear() - inflater?.inflate(R.menu.toolbar_report, menu) - this.editableMenu = menu - updateMenuUI() - super.onCreateOptionsMenu(menu, inflater) - } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item!!.itemId) { - R.id.save -> this.saveReportRequest() - } - return true + this.liveDataType = LiveData.REPORT_SETUP + this.saveButtonShouldAppear = this._selectedReport.options.userGenerated + this.deleteButtonShouldAppear = (this.primaryKey != null) } - /** - * Update menu UI - */ - private fun updateMenuUI() { - editableMenu?.findItem(R.id.save)?.let { - it.isVisible = this.selectedReport.options.userGenerated - it.icon.setTint(requireContext().getColor(R.color.white)) - } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + parentActivity = activity as PokerAnalyticsActivity + + // Avoid a bug during setting the titleResId + toolbar.title = "" + + parentActivity.setSupportActionBar(toolbar) + parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true) + setHasOptionsMenu(true) + + toolbar.title = reportTitle + } - private fun saveReportRequest() { + override fun saveData() { + + activity?.let { + val builder = AlertDialog.Builder(it) + // Get the layout inflater + val inflater = requireActivity().layoutInflater; + + // Inflate and set the layout for the dialog + // Pass null as the parent view because its going in the dialog layout + val view = inflater.inflate(R.layout.dialog_edit_text, null) + val nameEditText = view.findViewById(R.id.reportName) + builder.setView(view) + // Add action buttons + .setPositiveButton(R.string.save) { dialog, id -> + saveReport(nameEditText.text.toString()) + dialog.dismiss() + } + .setNegativeButton(R.string.cancel) { dialog, id -> + dialog.cancel() + } + + val dialog = builder.create() + dialog.show() + + } ?: throw IllegalStateException("Activity cannot be null") + } private fun saveReport(name: String) { - getRealm().executeTransaction { - val report = this.selectedReport.options.reportSetup(name) - it.insert(report) + getRealm().executeTransaction { realm -> + + val rs = this.item as ReportSetup + + val options = this._selectedReport.options + rs.name = name + rs.display = options.display.ordinal + options.stats.forEach { + rs.statIds.add(it.uniqueIdentifier) + } + options.criterias.forEach { + rs.criteriaIds.add(it.uniqueIdentifier) + } + rs.filter = options.filter + + this.item = rs + + this.deleteButtonShouldAppear = true + toolbar.title = name + realm.copyToRealmOrUpdate(rs) } + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComparisonReportFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComparisonReportFragment.kt index 3d93fa50..5750e3c7 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComparisonReportFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComparisonReportFragment.kt @@ -13,28 +13,22 @@ import net.pokeranalytics.android.ui.adapter.ReportPagerAdapter class ComparisonReportFragment : AbstractReportFragment() { companion object { - fun newInstance(report: Report?, reportTitle: String): ComparisonReportFragment { + + fun newInstance(report: Report, reportTitle: String): ComparisonReportFragment { val fragment = ComparisonReportFragment() fragment.reportTitle = reportTitle - report?.let { - fragment.selectedReport = it - } + fragment.setReport(report) val bundle = Bundle() fragment.arguments = bundle return fragment - } } -// private var reports: MutableMap = hashMapOf() -// private var stat: Stat = Stat.NET_RESULT -// private var displayAggregationChoices: Boolean = true - /** * Set data */ fun setData(report: Report) { - this.selectedReport = report + this.setReport(report) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComposableTableReportFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComposableTableReportFragment.kt index 9fc6c7a8..734ed4b2 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComposableTableReportFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComposableTableReportFragment.kt @@ -12,7 +12,7 @@ import kotlinx.coroutines.* import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.* import net.pokeranalytics.android.model.realm.ComputableResult -import net.pokeranalytics.android.ui.activity.ProgressReportActivity +import net.pokeranalytics.android.ui.activity.components.ReportActivity import net.pokeranalytics.android.ui.adapter.DisplayDescriptor import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate @@ -212,7 +212,11 @@ open class ComposableTableReportFragment : RealmFragment(), StaticRowRepresentab if (!isDetached) { hideLoader() report?.let { - ProgressReportActivity.newInstance(requireContext(), stat, it) + val title = stat.localizedTitle(requireContext()) + + ReportActivity.newInstance(requireContext(), it, title, stat) + +// ProgressReportActivity.newInstance(requireContext(), stat, it, title = title) } } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ProgressReportFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ProgressReportFragment.kt index fa1d98c2..b797d56a 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ProgressReportFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ProgressReportFragment.kt @@ -64,9 +64,9 @@ class ProgressReportFragment : AbstractReportFragment() { /** * Set data */ - fun setData(stat: Stat, report: Report, displayAggregationChoices: Boolean, title: String? = null) { + fun setData(report: Report, stat: Stat, displayAggregationChoices: Boolean, title: String) { this.stat = stat - this.selectedReport = report + this.setReport(report) this.displayAggregationChoices = displayAggregationChoices this.reportTitle = title @@ -80,15 +80,12 @@ class ProgressReportFragment : AbstractReportFragment() { */ private fun initUI() { - setDisplayHomeAsUpEnabled(true) - setToolbarTitle(this.reportTitle ?: stat.localizedTitle(requireContext())) - - val fragmentManager = parentActivity?.supportFragmentManager - val fragmentTransaction = fragmentManager?.beginTransaction() + val fragmentManager = parentActivity.supportFragmentManager + val fragmentTransaction = fragmentManager.beginTransaction() graphFragment = GraphFragment() - fragmentTransaction?.add(R.id.graphContainer, graphFragment) - fragmentTransaction?.commit() + fragmentTransaction.add(R.id.graphContainer, graphFragment) + fragmentTransaction.commit() stat.aggregationTypes.firstOrNull()?.let { aggregationType -> reports[aggregationType]?.let { report -> diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/TableReportFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/TableReportFragment.kt index 59c70e84..34e9e225 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/TableReportFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/report/TableReportFragment.kt @@ -13,15 +13,10 @@ class TableReportFragment : AbstractReportFragment() { companion object { - /** - * Create new instance - */ - fun newInstance(report: Report? = null, title: String? = null): TableReportFragment { + fun newInstance(report: Report, title: String): TableReportFragment { val fragment = TableReportFragment() fragment.reportTitle = title - report?.let { - fragment.selectedReport = it - } + fragment.setReport(report) val bundle = Bundle() fragment.arguments = bundle return fragment 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 diff --git a/app/src/main/res/layout/dialog_edit_text.xml b/app/src/main/res/layout/dialog_edit_text.xml new file mode 100644 index 00000000..3c1b82ec --- /dev/null +++ b/app/src/main/res/layout/dialog_edit_text.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/app/src/main/res/layout/fragment_bankroll.xml b/app/src/main/res/layout/fragment_bankroll.xml index 6c8114a4..b4340482 100644 --- a/app/src/main/res/layout/fragment_bankroll.xml +++ b/app/src/main/res/layout/fragment_bankroll.xml @@ -1,7 +1,7 @@ diff --git a/app/src/main/res/layout/fragment_data_list.xml b/app/src/main/res/layout/fragment_data_list.xml index 03650077..034a120d 100644 --- a/app/src/main/res/layout/fragment_data_list.xml +++ b/app/src/main/res/layout/fragment_data_list.xml @@ -2,7 +2,7 @@ diff --git a/app/src/main/res/layout/fragment_reports.xml b/app/src/main/res/layout/fragment_reports.xml index f7a184d4..e9cbb72e 100644 --- a/app/src/main/res/layout/fragment_reports.xml +++ b/app/src/main/res/layout/fragment_reports.xml @@ -1,6 +1,7 @@ diff --git a/app/src/main/res/layout/fragment_subscription.xml b/app/src/main/res/layout/fragment_subscription.xml index 587cb8e5..cfb103e1 100644 --- a/app/src/main/res/layout/fragment_subscription.xml +++ b/app/src/main/res/layout/fragment_subscription.xml @@ -39,6 +39,7 @@ Select a filter or launch report Launch Report Progress + Save Report Address Naming suggestions