From 8f74cffd74ddee3d7a2b4b8b2306c6dd671c6453 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Wed, 20 Feb 2019 18:00:16 +0100 Subject: [PATCH] add save and delete management on objects from settings --- .../pokeranalytics/android/model/LiveData.kt | 46 ++++++++++-- .../android/model/realm/Bankroll.kt | 3 +- .../android/model/realm/Game.kt | 10 ++- .../ui/fragment/EditableDataFragment.kt | 47 +++++++++++-- .../android/ui/view/RowRepresentable.kt | 70 +++++++++++++++---- .../res/layout/fragment_editable_data.xml | 20 +++++- app/src/main/res/values/strings.xml | 2 + 7 files changed, 167 insertions(+), 31 deletions(-) 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 f54b5fd8..7bb063cf 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/LiveData.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/LiveData.kt @@ -4,14 +4,25 @@ import io.realm.Realm import io.realm.RealmObject import io.realm.RealmResults import io.realm.Sort +import net.pokeranalytics.android.R import net.pokeranalytics.android.model.realm.* -import java.util.* +import net.pokeranalytics.android.ui.view.Localizable -enum class LiveData { +/** + * An interface to easily handle the validity of any object we want to save + */ +interface ObjectSavable { + fun isSavable(): Boolean { return true } +} + +/** + * An enum managing the business objects related to a realm results + */ +enum class LiveData : Localizable { BANKROLL, GAME, LOCATION, - TOURNAMENT_TYPE, + TOURNAMENT_FEATURE, TRANSACTION_TYPE; fun items(realm: Realm, fieldName: String? = null, sortOrder: Sort? = null): RealmResults<*> { @@ -28,11 +39,21 @@ enum class LiveData { BANKROLL -> Bankroll::class.java GAME -> Game::class.java LOCATION -> Location::class.java - TOURNAMENT_TYPE -> TournamentFeature::class.java + TOURNAMENT_FEATURE -> TournamentFeature::class.java TRANSACTION_TYPE -> TransactionType::class.java } } + fun newEntity(): RealmObject { + return when (this) { + BANKROLL -> Bankroll() + GAME -> Game() + LOCATION -> Location() + TOURNAMENT_FEATURE -> TournamentFeature() + TRANSACTION_TYPE -> TransactionType() + } + } + fun getData(realm:Realm, primaryKey:String?): RealmObject? { var proxyItem: RealmObject? = null primaryKey?.let { @@ -49,13 +70,24 @@ enum class LiveData { proxyItem?.let { return realm.copyFromRealm(it) } ?: run { - realm.beginTransaction() + return this.newEntity() +/* realm.beginTransaction() val t = realm.createObject(this.relatedEntity, UUID.randomUUID().toString()) realm.commitTransaction() - return realm.copyFromRealm(t) + return realm.copyFromRealm(t)*/ } } -} + + override val resId: Int? + get() { + return when (this) { + BANKROLL -> R.string.bankroll + GAME -> R.string.game + LOCATION -> R.string.location + TOURNAMENT_FEATURE -> R.string.tournament_type + TRANSACTION_TYPE -> R.string.operation_types + } + }} /* interface ListableDataSource { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt index bf23ca9c..d33a9174 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt @@ -4,6 +4,7 @@ import android.text.InputType import io.realm.RealmList import io.realm.RealmObject import io.realm.annotations.PrimaryKey +import net.pokeranalytics.android.model.ObjectSavable import net.pokeranalytics.android.ui.adapter.components.LiveDataDataSource import net.pokeranalytics.android.ui.adapter.components.RowRepresentableDataSource import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetData @@ -15,7 +16,7 @@ import java.util.* import kotlin.collections.ArrayList open class Bankroll(name: String = "") : RealmObject(), RowRepresentableDataSource, LiveDataDataSource, - RowEditable { + RowEditable, ObjectSavable { companion object { fun newInstance() : Bankroll { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt index c0a419a1..2006af81 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt @@ -3,6 +3,7 @@ package net.pokeranalytics.android.model.realm import android.text.InputType import io.realm.RealmObject import io.realm.annotations.PrimaryKey +import net.pokeranalytics.android.model.ObjectSavable import net.pokeranalytics.android.ui.adapter.components.* import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetData import net.pokeranalytics.android.ui.view.RowEditable @@ -11,7 +12,7 @@ import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.SimpleRow import java.util.* -open class Game : RealmObject(), RowRepresentableDataSource, LiveDataDataSource, RowEditable { +open class Game : RealmObject(), RowRepresentableDataSource, LiveDataDataSource, RowEditable, ObjectSavable { @PrimaryKey var id = UUID.randomUUID().toString() @@ -35,6 +36,7 @@ open class Game : RealmObject(), RowRepresentableDataSource, LiveDataDataSource, override fun stringForRow(row: RowRepresentable): String { return when (row) { SimpleRow.NAME -> this.name + GameRow.SHORT_NAME -> this.shortName?:"" else -> return super.stringForRow(row) } } @@ -43,6 +45,7 @@ open class Game : RealmObject(), RowRepresentableDataSource, LiveDataDataSource, val data = java.util.ArrayList() when (row) { SimpleRow.NAME -> data.add(BottomSheetData(this.name, SimpleRow.NAME.resId, InputType.TYPE_CLASS_TEXT)) + GameRow.SHORT_NAME -> data.add(BottomSheetData(this.shortName, GameRow.SHORT_NAME.resId, InputType.TYPE_CLASS_TEXT)) } return data } @@ -50,6 +53,11 @@ open class Game : RealmObject(), RowRepresentableDataSource, LiveDataDataSource, override fun updateValue(value: Any?, row: RowRepresentable) { when (row) { SimpleRow.NAME -> this.name = value as String? ?: "" + GameRow.SHORT_NAME -> this.shortName = value as String } } + + override fun isSavable(): Boolean { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt index 7a1041b0..2635cc08 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt @@ -1,10 +1,12 @@ package net.pokeranalytics.android.ui.fragment +import android.content.DialogInterface import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast +import androidx.appcompat.app.AlertDialog import androidx.recyclerview.widget.LinearLayoutManager import io.realm.Realm import io.realm.RealmObject @@ -12,6 +14,7 @@ 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.model.LiveData +import net.pokeranalytics.android.model.ObjectSavable import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.adapter.components.* import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment @@ -78,26 +81,56 @@ class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, setHasFixedSize(true) layoutManager = viewManager } + + this.saveButton.text = this.saveButton.context.getString(R.string.save) + this.saveButton.setOnClickListener { + + if ((this.item as ObjectSavable).isSavable()) { + this.getRealm().executeTransaction { + it.copyToRealmOrUpdate(this.item) + } + this.activity?.let { + it.finish() + } + } else { + val builder = AlertDialog.Builder(it.context) + builder.setTitle(R.string.warning) + .setNegativeButton(R.string.ok, null) + builder.show() + } + } + + this.deleteButton.text = this.deleteButton.context.getString(R.string.delete) + this.deleteButton.setOnClickListener { + val builder = AlertDialog.Builder(it.context) + builder.setTitle(R.string.warning) + .setMessage(R.string.are_you_sure_you_want_to_do_that_) + .setNeutralButton(R.string.no, null) + .setNegativeButton(R.string.yes, DialogInterface.OnClickListener { dialog, id -> + this.getRealm().executeTransaction { + this.item.deleteFromRealm() + } + this.activity?.let { + it.finish() + } + }) + builder.show() + } } /** * Set fragment data */ fun setData(dataType: Int, primaryKey: String?) { - this.liveDataType = LiveData.values()[dataType] - val realm = Realm.getDefaultInstance() - var proxyItem : RealmObject? = this.liveDataType.getData(realm, primaryKey) + var proxyItem : RealmObject? = this.liveDataType.getData(this.getRealm(), primaryKey) proxyItem?.let { this.appBar.toolbar.title = "Update ${this.liveDataType.name.toLowerCase().capitalize()}" } ?: run { this.appBar.toolbar.title = "New ${this.liveDataType.name.toLowerCase().capitalize()}" } - - this.item = this.liveDataType.updateOrCreate(realm, primaryKey) - + this.item = this.liveDataType.updateOrCreate(this.getRealm(), primaryKey) this.rowRepresentableAdapter = RowRepresentableAdapter((this.item as RowRepresentableDataSource), this) this.recyclerView.adapter = rowRepresentableAdapter - } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt index 58157e5d..6c19108b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt @@ -6,11 +6,9 @@ import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType /** - * An interface used so that enums values can be represented visually - * as rows in RecyclerViews + * An interface to easily localize any object */ -interface RowRepresentable { - +interface Localizable { /** * The resource identifier of the localized title */ @@ -28,7 +26,13 @@ interface RowRepresentable { } return "LOCALISATION NOT FOUND" } +} +/** + * An interface used so that enums values can be represented visually + * as rows in RecyclerViews + */ +interface RowRepresentable : Localizable { /** * The type of view associated with the row */ @@ -130,9 +134,53 @@ enum class BankrollRow : RowRepresentable { } enum class GameRow : RowRepresentable { + SHORT_NAME; + + override val resId: Int? + get() { + return when (this) { + SHORT_NAME -> R.string.short_name + } + } + + override val viewType: Int + get() { + return when (this) { + SHORT_NAME -> RowViewType.TITLE_VALUE.ordinal + } + } + + override val bottomSheetType: BottomSheetType + get() { + return when (this) { + SHORT_NAME -> BottomSheetType.EDIT_TEXT + } + } } enum class LocationRow : RowRepresentable { + LOCATION_STATUS; + + override val resId: Int? + get() { + return when (this) { + LOCATION_STATUS -> R.string.short_name + } + } + + override val viewType: Int + get() { + return when (this) { + LOCATION_STATUS -> RowViewType.TITLE.ordinal + } + } + + override val bottomSheetType: BottomSheetType + get() { + return when (this) { + LOCATION_STATUS -> BottomSheetType.NONE + } + } } enum class TransactionTypeRow : RowRepresentable { @@ -145,17 +193,15 @@ enum class SettingRow: RowRepresentable { BANKROLL, GAME, LOCATION, - TOURNAMENT_TYPE, + TOURNAMENT_FEATURE, TRANSACTION_TYPE; override val resId: Int? get() { - return when (this) { - BANKROLL -> R.string.bankroll - GAME -> R.string.game - LOCATION -> R.string.location - TOURNAMENT_TYPE -> R.string.tournament_type - TRANSACTION_TYPE -> R.string.operation_types + this.relatedResultsRepresentable?. let { + return it.resId + } ?: run { + return super.resId } } @@ -167,7 +213,7 @@ enum class SettingRow: RowRepresentable { BANKROLL -> LiveData.BANKROLL GAME -> LiveData.GAME LOCATION -> LiveData.LOCATION - TOURNAMENT_TYPE -> LiveData.TOURNAMENT_TYPE + TOURNAMENT_FEATURE -> LiveData.TOURNAMENT_FEATURE TRANSACTION_TYPE -> LiveData.TRANSACTION_TYPE } } diff --git a/app/src/main/res/layout/fragment_editable_data.xml b/app/src/main/res/layout/fragment_editable_data.xml index d072701e..ed7b8bf4 100644 --- a/app/src/main/res/layout/fragment_editable_data.xml +++ b/app/src/main/res/layout/fragment_editable_data.xml @@ -9,7 +9,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" - app:layout_behavior="@string/appbar_scrolling_view_behavior"> + app:layout_behavior="@string/appbar_scrolling_view_behavior" android:id="@+id/nestedScrollView"> + app:layout_constraintTop_toTopOf="parent"/> @@ -51,10 +51,24 @@ android:layout_height="?attr/actionBarSize" app:title="Poker Analytics" app:titleTextColor="@color/white" - app:layout_collapseMode="pin" /> + app:layout_collapseMode="pin"/> +