1
0
Fork 1
forked from suyu/suyu

Attempt to move the unzip coroutine to a ViewModel

This commit is contained in:
PabloG02 2023-06-04 02:24:14 +02:00
parent 72597b8ffe
commit 3733187c14
3 changed files with 94 additions and 27 deletions

View file

@ -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
}

View file

@ -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<Any>()
val result: LiveData<Any> = _result
private val _isComplete = MutableLiveData<Boolean>()
val isComplete: LiveData<Boolean> = _isComplete
private val _isRunning = MutableLiveData<Boolean>()
val isRunning: LiveData<Boolean> = _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)
}
}
}

View file

@ -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(
messageToShow = MessageDialogFragment.newInstance(
R.string.firmware_installed_failure,
R.string.firmware_installed_failure_description
).show(supportFragmentManager, MessageDialogFragment.TAG)
}
)
} 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 =