commit
595bea05a6
@ -0,0 +1,114 @@ |
|||||||
|
package net.pokeranalytics.android.ui.fragment |
||||||
|
|
||||||
|
import android.os.Bundle |
||||||
|
import android.view.View |
||||||
|
import androidx.appcompat.app.AlertDialog |
||||||
|
import androidx.coordinatorlayout.widget.CoordinatorLayout |
||||||
|
import com.google.android.material.snackbar.Snackbar |
||||||
|
import io.realm.RealmObject |
||||||
|
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 |
||||||
|
|
||||||
|
/** |
||||||
|
* 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() { |
||||||
|
|
||||||
|
private var deletedItem: RealmObject? = null |
||||||
|
private var lastDeletedItemPosition: Int = 0 |
||||||
|
private var dataListAdapter: RowRepresentableAdapter? = null |
||||||
|
private var coordinatorLayout: CoordinatorLayout? = null |
||||||
|
private var snackBar: Snackbar? = null |
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
||||||
|
super.onViewCreated(view, savedInstanceState) |
||||||
|
this.coordinatorLayout = view.findViewById(R.id.coordinatorLayout) |
||||||
|
} |
||||||
|
|
||||||
|
override fun onPause() { |
||||||
|
super.onPause() |
||||||
|
snackBar?.dismiss() |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Delete item |
||||||
|
* [dataListAdapter]: Adapter to update |
||||||
|
* [items]: List of items which contains the element to delete |
||||||
|
* [itemId]: Id of the item to delete |
||||||
|
* [container]: View to display the Snackbar |
||||||
|
*/ |
||||||
|
fun deleteItem(dataListAdapter: RowRepresentableAdapter, items: List<*>, itemId: String) { |
||||||
|
|
||||||
|
if (isDetached || activity == null) { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
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 } |
||||||
|
|
||||||
|
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() |
||||||
|
} |
||||||
|
updateUIAfterDeletion(itemPosition) |
||||||
|
showUndoSnackBar() |
||||||
|
} 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() { |
||||||
|
val message = String.format(getString(R.string.data_deleted)) |
||||||
|
this.coordinatorLayout?.let { view -> |
||||||
|
snackBar = Snackbar.make(view, message, Snackbar.LENGTH_INDEFINITE) |
||||||
|
snackBar?.setAction(R.string.cancel) { |
||||||
|
getRealm().executeTransaction { realm -> |
||||||
|
deletedItem?.let { |
||||||
|
val item = realm.copyToRealmOrUpdate(it) |
||||||
|
updateUIAfterUndoDeletion(item) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
snackBar?.show() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Called once the object has been deleted |
||||||
|
*/ |
||||||
|
open fun updateUIAfterDeletion(itemPosition: Int) { |
||||||
|
dataListAdapter?.notifyItemRemoved(itemPosition) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Called once the object has been restored |
||||||
|
*/ |
||||||
|
open fun updateUIAfterUndoDeletion(newItem: RealmObject) { |
||||||
|
dataListAdapter?.notifyItemInserted(lastDeletedItemPosition) |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -1,6 +1,33 @@ |
|||||||
package net.pokeranalytics.android.ui.view.rowrepresentable |
package net.pokeranalytics.android.ui.view.rowrepresentable |
||||||
|
|
||||||
|
import net.pokeranalytics.android.R |
||||||
|
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType |
||||||
import net.pokeranalytics.android.ui.view.DefaultEditDataSource |
import net.pokeranalytics.android.ui.view.DefaultEditDataSource |
||||||
import net.pokeranalytics.android.ui.view.RowRepresentable |
import net.pokeranalytics.android.ui.view.RowRepresentable |
||||||
|
import net.pokeranalytics.android.ui.view.RowViewType |
||||||
|
|
||||||
enum class TransactionTypeRow : RowRepresentable, DefaultEditDataSource |
enum class TransactionTypeRow : RowRepresentable, DefaultEditDataSource { |
||||||
|
TRANSACTION_ADDITIVE; |
||||||
|
|
||||||
|
override val resId: Int? |
||||||
|
get() { |
||||||
|
return when (this) { |
||||||
|
TRANSACTION_ADDITIVE -> R.string.additive |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override val viewType: Int |
||||||
|
get() { |
||||||
|
return when (this) { |
||||||
|
TRANSACTION_ADDITIVE -> RowViewType.TITLE_SWITCH.ordinal |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override val bottomSheetType: BottomSheetType |
||||||
|
get() { |
||||||
|
return when (this) { |
||||||
|
TRANSACTION_ADDITIVE -> BottomSheetType.NONE |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|||||||
@ -1,137 +1,118 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
<?xml version="1.0" encoding="utf-8"?> |
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" |
<androidx.constraintlayout.widget.ConstraintLayout |
||||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
xmlns:tools="http://schemas.android.com/tools" |
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
android:id="@+id/container" |
xmlns:tools="http://schemas.android.com/tools" |
||||||
android:layout_width="match_parent" |
android:id="@+id/container" |
||||||
android:layout_height="match_parent" |
android:layout_width="match_parent" |
||||||
tools:context=".ui.activity.HomeActivity"> |
android:layout_height="match_parent" |
||||||
|
tools:context=".ui.activity.HomeActivity"> |
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout |
<com.google.android.material.appbar.AppBarLayout |
||||||
android:id="@+id/appBar" |
android:id="@+id/appBar" |
||||||
android:layout_width="0dp" |
android:layout_width="0dp" |
||||||
android:layout_height="wrap_content" |
|
||||||
android:theme="@style/PokerAnalyticsTheme.Toolbar.Session" |
|
||||||
app:layout_constraintEnd_toEndOf="parent" |
|
||||||
app:layout_constraintStart_toStartOf="parent" |
|
||||||
app:layout_constraintTop_toTopOf="parent"> |
|
||||||
|
|
||||||
<LinearLayout |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="wrap_content" |
android:layout_height="wrap_content" |
||||||
android:gravity="center" |
android:theme="@style/PokerAnalyticsTheme.Toolbar.Session" |
||||||
android:orientation="horizontal" |
app:layout_constraintEnd_toEndOf="parent" |
||||||
android:padding="8dp"> |
app:layout_constraintStart_toStartOf="parent" |
||||||
|
app:layout_constraintTop_toTopOf="parent"> |
||||||
<com.google.android.material.chip.ChipGroup |
|
||||||
android:id="@+id/filters" |
<com.google.android.material.tabs.TabLayout |
||||||
android:layout_width="wrap_content" |
android:id="@+id/tabs" |
||||||
|
android:layout_width="match_parent" |
||||||
android:layout_height="wrap_content" |
android:layout_height="wrap_content" |
||||||
app:chipSpacing="8dp" |
app:tabMode="fixed"> |
||||||
app:singleSelection="true"> |
|
||||||
|
|
||||||
<!-- |
|
||||||
<com.google.android.material.chip.Chip |
|
||||||
android:id="@+id/filterAll" |
|
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:checked="true" |
|
||||||
android:text="@string/all" /> |
|
||||||
--> |
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip |
<com.google.android.material.tabs.TabItem |
||||||
android:id="@+id/filterSessions" |
android:id="@+id/filterSessions" |
||||||
android:layout_width="wrap_content" |
android:layout_width="wrap_content" |
||||||
android:layout_height="wrap_content" |
android:layout_height="wrap_content" |
||||||
android:checked="true" |
android:text="@string/sessions"/> |
||||||
android:text="@string/sessions" /> |
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip |
<com.google.android.material.tabs.TabItem |
||||||
android:id="@+id/filterTransactions" |
android:id="@+id/filterTransactions" |
||||||
android:layout_width="wrap_content" |
android:layout_width="wrap_content" |
||||||
android:layout_height="wrap_content" |
android:layout_height="wrap_content" |
||||||
android:text="@string/operations" /> |
android:text="@string/operations"/> |
||||||
|
|
||||||
</com.google.android.material.chip.ChipGroup> |
</com.google.android.material.tabs.TabLayout> |
||||||
|
|
||||||
</LinearLayout> |
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout> |
</com.google.android.material.appbar.AppBarLayout> |
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView |
<androidx.recyclerview.widget.RecyclerView |
||||||
android:id="@+id/recyclerView" |
android:id="@+id/recyclerView" |
||||||
android:layout_width="0dp" |
android:layout_width="0dp" |
||||||
android:layout_height="0dp" |
android:layout_height="0dp" |
||||||
app:layout_constraintBottom_toBottomOf="parent" |
app:layout_constraintBottom_toBottomOf="parent" |
||||||
app:layout_constraintEnd_toEndOf="parent" |
app:layout_constraintEnd_toEndOf="parent" |
||||||
app:layout_constraintStart_toStartOf="parent" |
app:layout_constraintStart_toStartOf="parent" |
||||||
app:layout_constraintTop_toBottomOf="@+id/appBar" |
app:layout_constraintTop_toBottomOf="@+id/appBar" |
||||||
tools:listitem="@layout/row_feed_session" /> |
tools:listitem="@layout/row_feed_session"/> |
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView |
<androidx.appcompat.widget.AppCompatTextView |
||||||
android:id="@+id/noSessionFound" |
android:id="@+id/noSessionFound" |
||||||
style="@style/PokerAnalyticsTheme.TextView.Header" |
style="@style/PokerAnalyticsTheme.TextView.Header" |
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_marginStart="8dp" |
|
||||||
android:layout_marginTop="8dp" |
|
||||||
android:layout_marginEnd="8dp" |
|
||||||
android:layout_marginBottom="8dp" |
|
||||||
android:text="@string/no_sessions" |
|
||||||
android:textSize="24sp" |
|
||||||
android:visibility="gone" |
|
||||||
app:layout_constraintBottom_toBottomOf="parent" |
|
||||||
app:layout_constraintEnd_toEndOf="parent" |
|
||||||
app:layout_constraintStart_toStartOf="parent" |
|
||||||
app:layout_constraintTop_toTopOf="parent" |
|
||||||
app:layout_constraintVertical_bias="0.5" |
|
||||||
tools:visibility="visible" /> |
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton |
|
||||||
android:id="@+id/addButton" |
|
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_gravity="bottom|end" |
|
||||||
android:layout_marginEnd="16dp" |
|
||||||
android:layout_marginBottom="16dp" |
|
||||||
android:src="@drawable/ic_add" |
|
||||||
android:tint="@color/black" |
|
||||||
android:transitionName="floating_action_button" |
|
||||||
app:fabSize="normal" |
|
||||||
app:layout_constraintBottom_toBottomOf="parent" |
|
||||||
app:layout_constraintEnd_toEndOf="parent" /> |
|
||||||
|
|
||||||
<androidx.appcompat.widget.LinearLayoutCompat |
|
||||||
android:id="@+id/disclaimerContainer" |
|
||||||
android:layout_width="0dp" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:background="@color/green_darker" |
|
||||||
android:orientation="vertical" |
|
||||||
android:padding="24dp" |
|
||||||
android:elevation="8dp" |
|
||||||
app:layout_constraintBottom_toBottomOf="parent" |
|
||||||
app:layout_constraintEnd_toEndOf="parent" |
|
||||||
app:layout_constraintStart_toStartOf="parent"> |
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView |
|
||||||
android:layout_width="wrap_content" |
android:layout_width="wrap_content" |
||||||
android:layout_height="wrap_content" |
android:layout_height="wrap_content" |
||||||
android:layout_marginStart="8dp" |
android:layout_marginStart="8dp" |
||||||
|
android:layout_marginTop="8dp" |
||||||
android:layout_marginEnd="8dp" |
android:layout_marginEnd="8dp" |
||||||
android:layout_marginBottom="8dp" |
android:layout_marginBottom="8dp" |
||||||
android:text="@string/disclaimer" |
android:text="@string/no_sessions" |
||||||
android:textSize="18sp" |
android:textSize="24sp" |
||||||
tools:visibility="visible" /> |
android:visibility="gone" |
||||||
|
app:layout_constraintBottom_toBottomOf="parent" |
||||||
|
app:layout_constraintEnd_toEndOf="parent" |
||||||
|
app:layout_constraintStart_toStartOf="parent" |
||||||
|
app:layout_constraintTop_toTopOf="parent" |
||||||
|
app:layout_constraintVertical_bias="0.5" |
||||||
|
tools:visibility="visible"/> |
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton |
<com.google.android.material.floatingactionbutton.FloatingActionButton |
||||||
android:id="@+id/disclaimerDismiss" |
android:id="@+id/addButton" |
||||||
style="@style/PokerAnalyticsTheme.Button" |
android:layout_width="wrap_content" |
||||||
android:layout_width="fill_parent" |
|
||||||
android:layout_height="wrap_content" |
android:layout_height="wrap_content" |
||||||
android:layout_marginStart="8dp" |
android:layout_gravity="bottom|end" |
||||||
android:layout_marginTop="8dp" |
|
||||||
android:layout_marginEnd="16dp" |
android:layout_marginEnd="16dp" |
||||||
android:text="@string/iunderstand" /> |
android:layout_marginBottom="16dp" |
||||||
|
android:src="@drawable/ic_add" |
||||||
|
android:tint="@color/black" |
||||||
|
android:transitionName="floating_action_button" |
||||||
|
app:fabSize="normal" |
||||||
|
app:layout_constraintBottom_toBottomOf="parent" |
||||||
|
app:layout_constraintEnd_toEndOf="parent"/> |
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat |
||||||
|
android:id="@+id/disclaimerContainer" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:background="@color/green_darker" |
||||||
|
android:orientation="vertical" |
||||||
|
android:padding="24dp" |
||||||
|
android:elevation="8dp" |
||||||
|
app:layout_constraintBottom_toBottomOf="parent" |
||||||
|
app:layout_constraintEnd_toEndOf="parent" |
||||||
|
app:layout_constraintStart_toStartOf="parent"> |
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginStart="8dp" |
||||||
|
android:layout_marginEnd="8dp" |
||||||
|
android:layout_marginBottom="8dp" |
||||||
|
android:text="@string/disclaimer" |
||||||
|
android:textSize="18sp" |
||||||
|
tools:visibility="visible"/> |
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton |
||||||
|
android:id="@+id/disclaimerDismiss" |
||||||
|
style="@style/PokerAnalyticsTheme.Button" |
||||||
|
android:layout_width="fill_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginStart="8dp" |
||||||
|
android:layout_marginTop="8dp" |
||||||
|
android:layout_marginEnd="16dp" |
||||||
|
android:text="@string/iunderstand"/> |
||||||
|
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat> |
</androidx.appcompat.widget.LinearLayoutCompat> |
||||||
|
|
||||||
|
|||||||
Loading…
Reference in new issue