From c812de48ea2f32d1887b4b68b1ba6e655c075a3c Mon Sep 17 00:00:00 2001 From: lynxnb Date: Sun, 31 Jul 2022 01:56:44 +0200 Subject: [PATCH] Show an undo button after deleting a gpu driver After a driver has been deleted, a snackbar will be shown confirming the deletion, with an button to undo it. --- .../emu/skyline/adapter/GenericAdapter.kt | 7 +++- .../emu/skyline/adapter/GpuDriverViewItem.kt | 10 ++--- .../skyline/preference/GpuDriverActivity.kt | 37 ++++++++++++++----- app/src/main/res/values/strings.xml | 1 + 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/emu/skyline/adapter/GenericAdapter.kt b/app/src/main/java/emu/skyline/adapter/GenericAdapter.kt index d4bd74ae..9dce5633 100644 --- a/app/src/main/java/emu/skyline/adapter/GenericAdapter.kt +++ b/app/src/main/java/emu/skyline/adapter/GenericAdapter.kt @@ -73,6 +73,11 @@ open class GenericAdapter : RecyclerView.Adapter> filter.filter(currentSearchTerm) } + open fun addItemAt(position : Int, item : GenericListItem) { + allItems.add(position, item) + filter.filter(currentSearchTerm) + } + fun setOnFilterPublishedListener(listener : OnFilterPublishedListener) { onFilterPublishedListener = listener } @@ -168,7 +173,7 @@ class SelectableGenericAdapter(private val defaultPosition : Int) : GenericAdapt /** * Removes the item at [position] from the list and updates the selected position accordingly */ - override fun removeItemAt(position: Int) { + override fun removeItemAt(position : Int) { super.removeItemAt(position) if (position < selectedPosition) selectedPosition-- diff --git a/app/src/main/java/emu/skyline/adapter/GpuDriverViewItem.kt b/app/src/main/java/emu/skyline/adapter/GpuDriverViewItem.kt index b42fdec5..f021e6e7 100644 --- a/app/src/main/java/emu/skyline/adapter/GpuDriverViewItem.kt +++ b/app/src/main/java/emu/skyline/adapter/GpuDriverViewItem.kt @@ -15,8 +15,8 @@ object GpuDriverBindingFactory : ViewBindingFactory { open class GpuDriverViewItem( val driverMetadata : GpuDriverMetadata, - private val onDelete : ((wasChecked : Boolean) -> Unit)? = null, - private val onClick : (() -> Unit)? = null + var onDelete : ((position : Int, wasChecked : Boolean) -> Unit)? = null, + var onClick : (() -> Unit)? = null ) : SelectableGenericListItem() { private var position = -1 @@ -42,15 +42,15 @@ open class GpuDriverViewItem( onClick?.invoke() } - if (onDelete != null) { + onDelete?.let { onDelete -> binding.deleteButton.visibility = ViewGroup.VISIBLE binding.deleteButton.setOnClickListener { val wasChecked = position == selectableAdapter?.selectedPosition selectableAdapter?.removeItemAt(position) - onDelete.invoke(wasChecked) + onDelete.invoke(position, wasChecked) } - } else { + } ?: run { binding.deleteButton.visibility = ViewGroup.GONE } } diff --git a/app/src/main/java/emu/skyline/preference/GpuDriverActivity.kt b/app/src/main/java/emu/skyline/preference/GpuDriverActivity.kt index 992f38cd..41536bfa 100644 --- a/app/src/main/java/emu/skyline/preference/GpuDriverActivity.kt +++ b/app/src/main/java/emu/skyline/preference/GpuDriverActivity.kt @@ -79,17 +79,36 @@ class GpuDriverActivity : AppCompatActivity() { } GpuDriverHelper.getInstalledDrivers(this).onEachIndexed { index, (file, metadata) -> - items.add(GpuDriverViewItem(metadata, { wasChecked -> - if (wasChecked) { - // If the deleted driver was the selected one, select the system driver - preferenceSettings.gpuDriver = PreferenceSettings.SYSTEM_GPU_DRIVER + items.add(GpuDriverViewItem(metadata).apply { + onDelete = { position, wasChecked -> + // If the driver was selected, select the system driver as the active one + if (wasChecked) + preferenceSettings.gpuDriver = PreferenceSettings.SYSTEM_GPU_DRIVER + + Snackbar.make(binding.root, "${metadata.label} deleted", Snackbar.LENGTH_LONG).setAction(R.string.undo) { + this@GpuDriverActivity.adapter.run { + addItemAt(position, this@apply) + // If the item was selected before removal, set it back as the active one when undoing + if (wasChecked) { + // Only notify previous to avoid notifying items before indexes have updated, the newly inserted item will be updated on bind + selectAndNotifyPrevious(position) + preferenceSettings.gpuDriver = metadata.label + } + } + }.addCallback(object : Snackbar.Callback() { + override fun onDismissed(transientBottomBar : Snackbar?, event : Int) { + // Only delete the driver directory if the user didn't undo the deletion + if (event != DISMISS_EVENT_ACTION) { + file.deleteRecursively() + } + } + }).show() } - if (!file.deleteRecursively()) { - Snackbar.make(binding.root, getString(R.string.gpu_driver_delete_failed), Snackbar.LENGTH_LONG).show() + + onClick = { + preferenceSettings.gpuDriver = metadata.label } - }, { - preferenceSettings.gpuDriver = metadata.label - })) + }) if (preferenceSettings.gpuDriver == metadata.label) { adapter.selectedPosition = index + 1 // Add 1 to account for the system driver entry diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a5aac3be..c695d17c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -184,4 +184,5 @@ Expand + Undo