From a1c0241a58c9b28ce24901633cd8d230f2cca357 Mon Sep 17 00:00:00 2001 From: davidoskky <davidoskky@yahoo.it> Date: Sun, 9 Mar 2025 13:49:32 +0000 Subject: [PATCH] Show a confirmation dialog before deleting sources (#185) ## Types of changes - [ x ] I have read the **CONTRIBUTING** document. - [ x ] My code follows the code style of this project. - [ ] I have updated the documentation accordingly. - [ ] I have added tests to cover my changes. - [ x ] All new and existing tests passed. - [ x ] This is **NOT** translation related. This is implements feature #156 I added a confirmation dialogue which pops up after tapping the delete source button. The popup displays the full name of the source to be deleted and allows the user to decide not to delete the source to prevent erroneous deletions. I moved most of the logic into the viewholder. Can be easily reverted if you prefer. All tests pass. I tested correct behavior in emulated versions of android API 25, 34 and 35. Co-authored-by: Amine <amine.bouabdallaoui@pm.me> Reviewed-on: https://gitea.amine-bouabdallaoui.fr/Louvorg/ReaderForSelfoss-multiplatform/pulls/185 Co-authored-by: davidoskky <davidoskky@yahoo.it> Co-committed-by: davidoskky <davidoskky@yahoo.it> --- .../android/adapters/SourcesListAdapter.kt | 127 ++++++++++-------- .../src/main/res/values-ca-rES/strings.xml | 2 + .../src/main/res/values-de-rDE/strings.xml | 2 + .../src/main/res/values-es-rES/strings.xml | 2 + .../src/main/res/values-fr-rFR/strings.xml | 2 + .../src/main/res/values-gl-rES/strings.xml | 2 + .../src/main/res/values-in-rID/strings.xml | 2 + .../src/main/res/values-it-rIT/strings.xml | 2 + .../src/main/res/values-ko-rKR/strings.xml | 2 + .../src/main/res/values-nl-rNL/strings.xml | 2 + .../src/main/res/values-pt-rBR/strings.xml | 2 + .../src/main/res/values-pt-rPT/strings.xml | 2 + .../src/main/res/values-si-rLK/strings.xml | 2 + .../src/main/res/values-tr-rTR/strings.xml | 2 + .../src/main/res/values-zh-rCN/strings.xml | 2 + .../src/main/res/values-zh-rTW/strings.xml | 2 + androidApp/src/main/res/values/strings.xml | 2 + 17 files changed, 104 insertions(+), 55 deletions(-) diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt index 0aa6d1ae..03c4b7ef 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt @@ -6,9 +6,8 @@ import android.content.Intent import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.Button import android.widget.Toast -import androidx.constraintlayout.widget.ConstraintLayout +import androidx.appcompat.app.AlertDialog import androidx.recyclerview.widget.RecyclerView import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.UpsertSourceActivity @@ -32,69 +31,21 @@ class SourcesListAdapter( private val items: ArrayList<SelfossModel.SourceDetail>, ) : RecyclerView.Adapter<SourcesListAdapter.ViewHolder>(), DIAware { - private val c: Context = app.baseContext - private lateinit var binding: SourceListItemBinding - override val di: DI by closestDI(app) - private val repository: Repository by instance() - private val appSettingsService: AppSettingsService by instance() override fun onCreateViewHolder( parent: ViewGroup, viewType: Int, ): ViewHolder { - binding = SourceListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return ViewHolder(binding.root) + val binding = SourceListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return ViewHolder(binding) } override fun onBindViewHolder( holder: ViewHolder, position: Int, ) { - val itm = items[position] - - val deleteBtn: Button = holder.mView.findViewById(R.id.deleteBtn) - - deleteBtn.setOnClickListener { - val (id, title) = items[position] - CoroutineScope(Dispatchers.IO).launch { - val successfullyDeletedSource = repository.deleteSource(id, title) - if (successfullyDeletedSource) { - items.removeAt(position) - notifyItemRemoved(position) - notifyItemRangeChanged(position, itemCount) - } else { - Toast - .makeText( - app, - R.string.can_delete_source, - Toast.LENGTH_SHORT, - ).show() - } - } - } - - holder.mView.setOnClickListener { - val source = items[position] - - repository.setSelectedSource(source) - app.startActivity(Intent(app, UpsertSourceActivity::class.java)) - } - - if (itm.getIcon(repository.baseUrl).isEmpty()) { - binding.itemImage.setBackgroundAndText(itm.title.getHtmlDecoded()) - } else { - c.circularDrawable(itm.getIcon(repository.baseUrl), binding.itemImage, appSettingsService) - } - - if (!itm.error.isNullOrBlank()) { - binding.errorText.visibility = View.VISIBLE - binding.errorText.text = itm.error - } else { - binding.errorText.visibility = View.GONE - } - - binding.sourceTitle.text = itm.title.getHtmlDecoded() + holder.bind(items[position], position) } override fun getItemId(position: Int) = position.toLong() @@ -104,6 +55,72 @@ class SourcesListAdapter( override fun getItemCount(): Int = items.size inner class ViewHolder( - val mView: ConstraintLayout, - ) : RecyclerView.ViewHolder(mView) + val binding: SourceListItemBinding, + ) : RecyclerView.ViewHolder(binding.root) { + private val context: Context = app.applicationContext + private val repository: Repository by instance() + private val appSettingsService: AppSettingsService by instance() + + fun bind( + source: SelfossModel.SourceDetail, + position: Int, + ) { + binding.apply { + sourceTitle.text = source.title.getHtmlDecoded() + if (source.getIcon(repository.baseUrl).isEmpty()) { + itemImage.setBackgroundAndText(source.title.getHtmlDecoded()) + } else { + context.circularDrawable(source.getIcon(repository.baseUrl), itemImage, appSettingsService) + } + + errorText.apply { + visibility = if (!source.error.isNullOrBlank()) View.VISIBLE else View.GONE + text = source.error + } + + deleteBtn.setOnClickListener { showDeleteConfirmationDialog(source, position) } + + root.setOnClickListener { + repository.setSelectedSource(source) + app.startActivity(Intent(app, UpsertSourceActivity::class.java)) + } + } + } + + private fun showDeleteConfirmationDialog( + source: SelfossModel.SourceDetail, + position: Int, + ) { + AlertDialog + .Builder(app) + .setTitle(app.getString(R.string.confirm_delete_title)) + .setMessage(app.getString(R.string.confirm_delete_message, source.title)) + .setPositiveButton(android.R.string.ok) { _, _ -> deleteSource(source, position) } + .setNegativeButton(android.R.string.cancel, null) + .show() + } + + private fun deleteSource( + source: SelfossModel.SourceDetail, + position: Int, + ) { + CoroutineScope(Dispatchers.IO).launch { + val successfullyDeletedSource = repository.deleteSource(source.id, source.title) + launch(Dispatchers.Main) { + if (successfullyDeletedSource) { + items.removeAt(position) + notifyItemRemoved(position) + notifyItemRangeChanged(position, itemCount) + } else { + Toast + .makeText( + app, + R.string.can_delete_source, + Toast.LENGTH_SHORT, + ).show() + } + } + } + } + } } diff --git a/androidApp/src/main/res/values-ca-rES/strings.xml b/androidApp/src/main/res/values-ca-rES/strings.xml index b49b5cab..c3bd1f70 100644 --- a/androidApp/src/main/res/values-ca-rES/strings.xml +++ b/androidApp/src/main/res/values-ca-rES/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"Quant a"</string> <string name="marked_as_read">"Element llegit"</string> <string name="marked_as_unread">"Item unread"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-de-rDE/strings.xml b/androidApp/src/main/res/values-de-rDE/strings.xml index 9e672304..7dfe940a 100644 --- a/androidApp/src/main/res/values-de-rDE/strings.xml +++ b/androidApp/src/main/res/values-de-rDE/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"Über"</string> <string name="marked_as_read">"Artikel gelesen"</string> <string name="marked_as_unread">"Item unread"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-es-rES/strings.xml b/androidApp/src/main/res/values-es-rES/strings.xml index 035c84d2..fb12df99 100644 --- a/androidApp/src/main/res/values-es-rES/strings.xml +++ b/androidApp/src/main/res/values-es-rES/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"Acerca de"</string> <string name="marked_as_read">"Artículo leído"</string> <string name="marked_as_unread">"Artículo no leído"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-fr-rFR/strings.xml b/androidApp/src/main/res/values-fr-rFR/strings.xml index 2fc0366c..07d553a8 100644 --- a/androidApp/src/main/res/values-fr-rFR/strings.xml +++ b/androidApp/src/main/res/values-fr-rFR/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"À propos"</string> <string name="marked_as_read">"Marqué comme lu"</string> <string name="marked_as_unread">"Marqué comme non lu"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-gl-rES/strings.xml b/androidApp/src/main/res/values-gl-rES/strings.xml index e3a3e389..e3576b03 100644 --- a/androidApp/src/main/res/values-gl-rES/strings.xml +++ b/androidApp/src/main/res/values-gl-rES/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"Acerca de"</string> <string name="marked_as_read">"Elemento lido"</string> <string name="marked_as_unread">"Elemento non lido"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-in-rID/strings.xml b/androidApp/src/main/res/values-in-rID/strings.xml index 8175827f..30eeaef7 100644 --- a/androidApp/src/main/res/values-in-rID/strings.xml +++ b/androidApp/src/main/res/values-in-rID/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"Tentang"</string> <string name="marked_as_read">"Membaca item"</string> <string name="marked_as_unread">"Item unread"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-it-rIT/strings.xml b/androidApp/src/main/res/values-it-rIT/strings.xml index 8bb17490..d11d45d3 100644 --- a/androidApp/src/main/res/values-it-rIT/strings.xml +++ b/androidApp/src/main/res/values-it-rIT/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"Informazioni"</string> <string name="marked_as_read">"Articolo letto"</string> <string name="marked_as_unread">"Item unread"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-ko-rKR/strings.xml b/androidApp/src/main/res/values-ko-rKR/strings.xml index 66920664..63c81b1e 100644 --- a/androidApp/src/main/res/values-ko-rKR/strings.xml +++ b/androidApp/src/main/res/values-ko-rKR/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"정보"</string> <string name="marked_as_read">"항목 읽기"</string> <string name="marked_as_unread">"Item unread"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-nl-rNL/strings.xml b/androidApp/src/main/res/values-nl-rNL/strings.xml index 43da71bb..3035383c 100644 --- a/androidApp/src/main/res/values-nl-rNL/strings.xml +++ b/androidApp/src/main/res/values-nl-rNL/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"Over"</string> <string name="marked_as_read">"Artikel gelezen"</string> <string name="marked_as_unread">"Item unread"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-pt-rBR/strings.xml b/androidApp/src/main/res/values-pt-rBR/strings.xml index c847693f..d3019324 100644 --- a/androidApp/src/main/res/values-pt-rBR/strings.xml +++ b/androidApp/src/main/res/values-pt-rBR/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"Sobre"</string> <string name="marked_as_read">"Item lido"</string> <string name="marked_as_unread">"Item unread"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-pt-rPT/strings.xml b/androidApp/src/main/res/values-pt-rPT/strings.xml index 41543a0e..fb4a81dc 100644 --- a/androidApp/src/main/res/values-pt-rPT/strings.xml +++ b/androidApp/src/main/res/values-pt-rPT/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"Sobre"</string> <string name="marked_as_read">"Item lido"</string> <string name="marked_as_unread">"Item unread"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-si-rLK/strings.xml b/androidApp/src/main/res/values-si-rLK/strings.xml index 9ad0b919..56179362 100644 --- a/androidApp/src/main/res/values-si-rLK/strings.xml +++ b/androidApp/src/main/res/values-si-rLK/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"මේ ගැන"</string> <string name="marked_as_read">"Item read"</string> <string name="marked_as_unread">"Item unread"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-tr-rTR/strings.xml b/androidApp/src/main/res/values-tr-rTR/strings.xml index 49252428..96b2912e 100644 --- a/androidApp/src/main/res/values-tr-rTR/strings.xml +++ b/androidApp/src/main/res/values-tr-rTR/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"Hakkında"</string> <string name="marked_as_read">"Öğeleri oku"</string> <string name="marked_as_unread">"Item unread"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-zh-rCN/strings.xml b/androidApp/src/main/res/values-zh-rCN/strings.xml index f8a132c8..a1ab3457 100644 --- a/androidApp/src/main/res/values-zh-rCN/strings.xml +++ b/androidApp/src/main/res/values-zh-rCN/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"关于我们"</string> <string name="marked_as_read">"已读"</string> <string name="marked_as_unread">"未读条目"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values-zh-rTW/strings.xml b/androidApp/src/main/res/values-zh-rTW/strings.xml index 108e15fc..dbf21a08 100644 --- a/androidApp/src/main/res/values-zh-rTW/strings.xml +++ b/androidApp/src/main/res/values-zh-rTW/strings.xml @@ -129,4 +129,6 @@ <string name="action_about">"关于我们"</string> <string name="marked_as_read">"已读"</string> <string name="marked_as_unread">"未讀項目"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources> diff --git a/androidApp/src/main/res/values/strings.xml b/androidApp/src/main/res/values/strings.xml index 8698e41c..d04a31ac 100644 --- a/androidApp/src/main/res/values/strings.xml +++ b/androidApp/src/main/res/values/strings.xml @@ -131,4 +131,6 @@ <string name="action_about">"About"</string> <string name="marked_as_read">"Item read"</string> <string name="marked_as_unread">"Item unread"</string> + <string name="confirm_delete_title">Confirm Deletion</string> + <string name="confirm_delete_message">Are you sure you want to delete the following source?\n%s</string> </resources>