From 3733187c147149c995df97d7ac72ab5e4aafd137 Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Sun, 4 Jun 2023 02:24:14 +0200 Subject: [PATCH] Attempt to move the unzip coroutine to a ViewModel --- .../IndeterminateProgressDialogFragment.kt | 40 +++++++++++++++++- .../org/yuzu/yuzu_emu/model/TaskViewModel.kt | 42 +++++++++++++++++++ .../org/yuzu/yuzu_emu/ui/main/MainActivity.kt | 39 +++++++---------- 3 files changed, 94 insertions(+), 27 deletions(-) create mode 100644 src/android/app/src/main/java/org/yuzu/yuzu_emu/model/TaskViewModel.kt diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/IndeterminateProgressDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/IndeterminateProgressDialogFragment.kt index edf7b8a3c..10a897392 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/IndeterminateProgressDialogFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/IndeterminateProgressDialogFragment.kt @@ -2,33 +2,69 @@ package org.yuzu.yuzu_emu.fragments import android.app.Dialog import android.os.Bundle +import android.widget.Toast import androidx.fragment.app.DialogFragment +import androidx.lifecycle.ViewModelProvider import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding +import org.yuzu.yuzu_emu.model.TaskViewModel +import java.io.Serializable + class IndeterminateProgressDialogFragment : DialogFragment() { + private lateinit var taskViewModel: TaskViewModel + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + taskViewModel = ViewModelProvider(requireActivity())[TaskViewModel::class.java] + val titleId = requireArguments().getInt(TITLE) val progressBinding = DialogProgressBarBinding.inflate(layoutInflater) progressBinding.progressBar.isIndeterminate = true - return MaterialAlertDialogBuilder(requireContext()) + val dialog = MaterialAlertDialogBuilder(requireContext()) .setTitle(titleId) .setView(progressBinding.root) - .show() + .create() + dialog.setCanceledOnTouchOutside(false) + + taskViewModel.isComplete.observe(this) { complete -> + if (complete) { + dialog.dismiss() + when (val result = taskViewModel.result.value) { + is String -> Toast.makeText(requireContext(), result, Toast.LENGTH_LONG).show() + is MessageDialogFragment -> result.show( + parentFragmentManager, + MessageDialogFragment.TAG + ) + } + taskViewModel.clear() + } + } + + if (taskViewModel.isRunning.value == false) { + val task = requireArguments().getSerializable(TASK) as? () -> Any + if (task != null) { + taskViewModel.task = task + taskViewModel.runTask() + } + } + return dialog } companion object { const val TAG = "IndeterminateProgressDialogFragment" private const val TITLE = "Title" + private const val TASK = "Task" fun newInstance( titleId: Int, + task: () -> Any ): IndeterminateProgressDialogFragment { val dialog = IndeterminateProgressDialogFragment() val args = Bundle() args.putInt(TITLE, titleId) + args.putSerializable(TASK, task as Serializable) dialog.arguments = args return dialog } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/TaskViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/TaskViewModel.kt new file mode 100644 index 000000000..23723bceb --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/TaskViewModel.kt @@ -0,0 +1,42 @@ +package org.yuzu.yuzu_emu.model + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class TaskViewModel : ViewModel() { + private val _result = MutableLiveData() + val result: LiveData = _result + + private val _isComplete = MutableLiveData() + val isComplete: LiveData = _isComplete + + private val _isRunning = MutableLiveData() + val isRunning: LiveData = _isRunning + + lateinit var task: () -> Any + + init { + clear() + } + + fun clear() { + _result.value = Any() + _isComplete.value = false + _isRunning.value = false + } + + fun runTask() { + if (_isRunning.value == true) return + _isRunning.value = true + + viewModelScope.launch(Dispatchers.IO) { + val res = task() + _result.postValue(res) + _isComplete.postValue(true) + } + } +} \ No newline at end of file diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt index bb8311023..2001ad704 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt @@ -26,7 +26,6 @@ import androidx.preference.PreferenceManager import com.google.android.material.color.MaterialColors import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.navigation.NavigationBarView -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -340,44 +339,34 @@ class MainActivity : AppCompatActivity(), ThemeProvider { File(DirectoryInitialization.userDirectory + "/nand/system/Contents/registered/") val cacheFirmwareDir = File("${cacheDir.path}/registered/") - val installingFirmwareDialog = IndeterminateProgressDialogFragment.newInstance( - R.string.firmware_installing - ) - installingFirmwareDialog.isCancelable = false - installingFirmwareDialog.show(supportFragmentManager, IndeterminateProgressDialogFragment.TAG) - - lifecycleScope.launch(Dispatchers.IO) { + val task: () -> Any = { + var messageToShow: Any try { FileUtil.unzip(inputZip, cacheFirmwareDir) val unfilteredNumOfFiles = cacheFirmwareDir.list()?.size ?: -1 val filteredNumOfFiles = cacheFirmwareDir.list(filterNCA)?.size ?: -2 if (unfilteredNumOfFiles != filteredNumOfFiles) { - withContext(Dispatchers.Main) { - installingFirmwareDialog.dismiss() - MessageDialogFragment.newInstance( - R.string.firmware_installed_failure, - R.string.firmware_installed_failure_description - ).show(supportFragmentManager, MessageDialogFragment.TAG) - } + messageToShow = MessageDialogFragment.newInstance( + R.string.firmware_installed_failure, + R.string.firmware_installed_failure_description + ) } else { firmwarePath.deleteRecursively() cacheFirmwareDir.copyRecursively(firmwarePath, true) - withContext(Dispatchers.Main) { - installingFirmwareDialog.dismiss() - Toast.makeText( - applicationContext, - getString(R.string.save_file_imported_success), - Toast.LENGTH_LONG - ).show() - } + messageToShow = getString(R.string.save_file_imported_success) } } catch (e: Exception) { - Toast.makeText(applicationContext, getString(R.string.fatal_error), Toast.LENGTH_LONG) - .show() + messageToShow = getString(R.string.fatal_error) } finally { cacheFirmwareDir.deleteRecursively() } + messageToShow } + + IndeterminateProgressDialogFragment.newInstance( + R.string.firmware_installing, + task + ).show(supportFragmentManager, IndeterminateProgressDialogFragment.TAG) } val getAmiiboKey =