From d243e8c7f8d2b148e5fd30819d91c71039e2b4cf Mon Sep 17 00:00:00 2001 From: deniscerri <64997243+deniscerri@users.noreply.github.com> Date: Tue, 26 Aug 2025 18:35:56 +0200 Subject: [PATCH] code refactor & wait for active downloads to pause before killing --- .../database/viewmodel/DownloadViewModel.kt | 2 +- .../deniscerri/ytdl/ui/more/MoreFragment.kt | 107 +++++++++--------- 2 files changed, 53 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/DownloadViewModel.kt b/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/DownloadViewModel.kt index 1fc9926e..6bc7480e 100644 --- a/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/DownloadViewModel.kt +++ b/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/DownloadViewModel.kt @@ -1370,7 +1370,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel updateToStatus(id, DownloadRepository.Status.Paused) } - fun pauseAllDownloads() = viewModelScope.launch { + suspend fun pauseAllDownloads() { pausedAllDownloads.value = PausedAllDownloadsState.PROCESSING isPausingResuming = true WorkManager.getInstance(application).cancelAllWorkByTag("download") diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/MoreFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/MoreFragment.kt index 0d5b1166..da28ba7a 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/MoreFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/MoreFragment.kt @@ -9,6 +9,7 @@ import android.view.View import android.view.ViewGroup import android.widget.CheckBox import android.widget.TextView +import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider @@ -114,62 +115,12 @@ class MoreFragment : Fragment() { findNavController().navigate(R.id.observeSourcesFragment) } - fun showTerminateConfirmationDialog() { - val shouldAskToTerminate = mainSharedPreferences.getBoolean("ask_terminate_app", true) - val isDoNotAskAgainChecked = !shouldAskToTerminate - var doNotShowAgainFinalState = isDoNotAskAgainChecked - - val terminateDialog = MaterialAlertDialogBuilder(requireContext()) - terminateDialog.setTitle(getString(R.string.confirm_terminate)) - val dialogView = layoutInflater.inflate(R.layout.dialog_terminate_app, null) - val checkbox = dialogView.findViewById(R.id.doNotShowAgain) - terminateDialog.setView(dialogView) - - checkbox.isChecked = doNotShowAgainFinalState - checkbox.setOnCheckedChangeListener { _, isChecked -> - doNotShowAgainFinalState = isChecked - } - - terminateDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface, _ -> - dialogInterface.cancel() - } - - terminateDialog.setPositiveButton(getString(R.string.ok)) { _, _ -> - lifecycleScope.launch { - downloadViewModel.pauseAllDownloads() - - mainSharedPreferencesEditor.putBoolean("ask_terminate_app", !doNotShowAgainFinalState).commit() - - mainActivity.finishAndRemoveTask() - mainActivity.finishAffinity() - exitProcess(0) - } - } - terminateDialog.show() - } - - // This handles the long press - terminateApp.setOnLongClickListener { - // A long press will ALWAYS show the dialog, ignoring the saved preference. - showTerminateConfirmationDialog() - - // Return true to indicate that the long click event is consumed - // and the regular OnClickListener should NOT be triggered. - true - } - - // This handles the regular (short) press terminateApp.setOnClickListener { - // Check the saved preference, just like before. - if (mainSharedPreferences.getBoolean("ask_terminate_app", true)) { - // If the user wants to be asked, show the dialog. - showTerminateConfirmationDialog() - } else { - // If they checked "Don't ask again", terminate immediately. - mainActivity.finishAndRemoveTask() - mainActivity.finishAffinity() - exitProcess(0) - } + showTerminateConfirmationDialog() + } + terminateApp.setOnLongClickListener { + showTerminateConfirmationDialog(skipPreference = true) + true } settings.setOnClickListener { @@ -179,6 +130,52 @@ class MoreFragment : Fragment() { } + fun showTerminateConfirmationDialog(skipPreference: Boolean = false) { + val shouldAskToTerminate = mainSharedPreferences.getBoolean("ask_terminate_app", true) + if (!shouldAskToTerminate && !skipPreference) { + terminateApp.isEnabled = false + terminateApp() + return + } + + var doNotShowAgainFinalState = !shouldAskToTerminate + + lateinit var dialog: AlertDialog + val terminateDialog = MaterialAlertDialogBuilder(requireContext()) + terminateDialog.setTitle(getString(R.string.confirm_terminate)) + val dialogView = layoutInflater.inflate(R.layout.dialog_terminate_app, null) + val checkbox = dialogView.findViewById(R.id.doNotShowAgain) + terminateDialog.setView(dialogView) + + checkbox.isChecked = doNotShowAgainFinalState + checkbox.setOnCheckedChangeListener { _, isChecked -> + doNotShowAgainFinalState = isChecked + } + + terminateDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface, _ -> + dialogInterface.cancel() + } + + terminateDialog.setPositiveButton(getString(R.string.ok), null) + dialog = terminateDialog.show() + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { + dialog.setCanceledOnTouchOutside(false) + dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false + dialog.getButton(AlertDialog.BUTTON_NEGATIVE).isEnabled = false + mainSharedPreferencesEditor.putBoolean("ask_terminate_app", !doNotShowAgainFinalState).commit() + terminateApp() + } + } + + fun terminateApp() { + lifecycleScope.launch { + downloadViewModel.pauseAllDownloads() + mainActivity.finishAndRemoveTask() + mainActivity.finishAffinity() + exitProcess(0) + } + } + companion object { const val TAG = "MoreFragment" }