Refactor data deletion, work in progress

dev
Aurelien Hubert 7 years ago
parent cef6cc966c
commit 91c9973ee0
  1. 67
      app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt
  2. 73
      app/src/main/java/net/pokeranalytics/android/ui/fragment/DeletableItemFragment.kt

@ -6,11 +6,8 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import io.realm.RealmObject
import io.realm.RealmResults import io.realm.RealmResults
import kotlinx.android.synthetic.main.fragment_data_list.* import kotlinx.android.synthetic.main.fragment_data_list.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -19,7 +16,6 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.interfaces.Deletable
import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.model.realm.Filter import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.DataListActivity
@ -29,12 +25,11 @@ import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.adapter.LiveRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.LiveRowRepresentableDataSource
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.helpers.SwipeToDeleteCallback import net.pokeranalytics.android.ui.helpers.SwipeToDeleteCallback
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.RowViewType
class DataListFragment : RealmFragment(), LiveRowRepresentableDataSource, RowRepresentableDelegate { class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource, RowRepresentableDelegate {
companion object { companion object {
const val REQUEST_CODE_DETAILS = 1000 const val REQUEST_CODE_DETAILS = 1000
@ -43,11 +38,9 @@ class DataListFragment : RealmFragment(), LiveRowRepresentableDataSource, RowRep
private lateinit var dataType: LiveData private lateinit var dataType: LiveData
private lateinit var items: RealmResults<*> private lateinit var items: RealmResults<*>
private lateinit var dataListAdapter: RowRepresentableAdapter private lateinit var dataListAdapter: RowRepresentableAdapter
private var deletedItem: RealmObject? = null
private var lastDeletedItemPosition: Int = 0
private var lastItemClickedId: String = "" private var lastItemClickedId: String = ""
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState) super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_data_list, container, false) return inflater.inflate(R.layout.fragment_data_list, container, false)
@ -66,7 +59,7 @@ class DataListFragment : RealmFragment(), LiveRowRepresentableDataSource, RowRep
if (needToDeleteItem) { if (needToDeleteItem) {
GlobalScope.launch(Dispatchers.Main) { GlobalScope.launch(Dispatchers.Main) {
delay(300) delay(300)
deleteItem(lastItemClickedId) deleteItem(dataListAdapter, items, lastItemClickedId)
} }
} }
} }
@ -126,7 +119,8 @@ class DataListFragment : RealmFragment(), LiveRowRepresentableDataSource, RowRep
dataListAdapter = RowRepresentableAdapter(this, this) dataListAdapter = RowRepresentableAdapter(this, this)
val swipeToDelete = SwipeToDeleteCallback(dataListAdapter) { position -> val swipeToDelete = SwipeToDeleteCallback(dataListAdapter) { position ->
deleteItem((this.items[position] as Identifiable).id) val itemId = (this.items[position] as Identifiable).id
deleteItem(dataListAdapter, items, itemId)
} }
val itemTouchHelper = ItemTouchHelper(swipeToDelete) val itemTouchHelper = ItemTouchHelper(swipeToDelete)
@ -149,57 +143,6 @@ class DataListFragment : RealmFragment(), LiveRowRepresentableDataSource, RowRep
} }
} }
/**
* Delete item
*/
private fun deleteItem(itemId: String) {
if (isDetached || activity == null) {
return
}
// Save the delete position & create a copy of the object
val itemPosition = this.items.indexOfFirst { (it as Identifiable).id == itemId }
val itemToDelete = this.items.find { (it as Identifiable).id == itemId }
if (itemToDelete is RealmObject && itemPosition != -1) {
// Check if the object is valid for the deletion
if ((itemToDelete as Deletable).isValidForDelete(this.getRealm())) {
deletedItem = getRealm().copyFromRealm(itemToDelete)
lastDeletedItemPosition = itemPosition
getRealm().executeTransaction {
itemToDelete.deleteFromRealm()
}
dataListAdapter.notifyItemRemoved(itemPosition)
showUndoSnackBar()
} else {
dataListAdapter.notifyItemChanged(itemPosition)
val builder = AlertDialog.Builder(requireContext())
.setMessage((itemToDelete as Deletable).getFailedDeleteMessage())
.setNegativeButton(R.string.ok, null)
builder.show()
}
}
}
/**
* Show undo snack bar
*/
private fun showUndoSnackBar() {
val message = String.format(getString(R.string.data_deleted), this.dataType.localizedTitle(requireContext()))
val snackBar = Snackbar.make(constraintLayout, message, Snackbar.LENGTH_INDEFINITE)
snackBar.setAction(R.string.cancel) {
getRealm().executeTransaction { realm ->
deletedItem?.let {
realm.copyToRealmOrUpdate(it)
dataListAdapter.notifyItemInserted(lastDeletedItemPosition)
}
}
}
snackBar.show()
}
/** /**
* Set fragment data * Set fragment data
*/ */

@ -0,0 +1,73 @@
package net.pokeranalytics.android.ui.fragment
import androidx.appcompat.app.AlertDialog
import com.google.android.material.snackbar.Snackbar
import io.realm.RealmObject
import kotlinx.android.synthetic.main.fragment_data_list.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.interfaces.Deletable
import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
open class DeletableItemFragment : RealmFragment() {
private var deletedItem: RealmObject? = null
private var lastDeletedItemPosition: Int = 0
/**
* Delete item
*/
fun deleteItem(dataListAdapter: RowRepresentableAdapter, items: List<*>, itemId: String) {
if (isDetached || activity == null) {
return
}
// 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 }
if (itemToDelete is RealmObject && itemPosition != -1) {
val deletableItem = (itemToDelete as Deletable)
// Check if the object is valid for the deletion
if (deletableItem.isValidForDelete(this.getRealm())) {
deletedItem = getRealm().copyFromRealm(itemToDelete)
lastDeletedItemPosition = itemPosition
getRealm().executeTransaction {
itemToDelete.deleteFromRealm()
}
dataListAdapter.notifyItemRemoved(itemPosition)
showUndoSnackBar(dataListAdapter)
} else {
dataListAdapter.notifyItemChanged(itemPosition)
val status = deletableItem.getDeleteStatus(this.getRealm())
val message = deletableItem.getFailedDeleteMessage(status)
val builder = AlertDialog.Builder(requireContext())
.setMessage(message)
.setNegativeButton(R.string.ok, null)
builder.show()
}
}
}
/**
* Show undo snack bar
*/
private fun showUndoSnackBar(dataListAdapter: RowRepresentableAdapter) {
val message = String.format(getString(R.string.data_deleted))
val snackBar = Snackbar.make(constraintLayout, message, Snackbar.LENGTH_INDEFINITE)
snackBar.setAction(R.string.cancel) {
getRealm().executeTransaction { realm ->
deletedItem?.let {
realm.copyToRealmOrUpdate(it)
dataListAdapter.notifyItemInserted(lastDeletedItemPosition)
}
}
}
snackBar.show()
}
}
Loading…
Cancel
Save