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.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.widget.Toast
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding
import org.yuzu.yuzu_emu.model.TaskViewModel
import java.io.Serializable
class IndeterminateProgressDialogFragment : DialogFragment() { class IndeterminateProgressDialogFragment : DialogFragment() {
private lateinit var taskViewModel: TaskViewModel
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
taskViewModel = ViewModelProvider(requireActivity())[TaskViewModel::class.java]
val titleId = requireArguments().getInt(TITLE) val titleId = requireArguments().getInt(TITLE)
val progressBinding = DialogProgressBarBinding.inflate(layoutInflater) val progressBinding = DialogProgressBarBinding.inflate(layoutInflater)
progressBinding.progressBar.isIndeterminate = true progressBinding.progressBar.isIndeterminate = true
return MaterialAlertDialogBuilder(requireContext()) val dialog = MaterialAlertDialogBuilder(requireContext())
.setTitle(titleId) .setTitle(titleId)
.setView(progressBinding.root) .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 { companion object {
const val TAG = "IndeterminateProgressDialogFragment" const val TAG = "IndeterminateProgressDialogFragment"
private const val TITLE = "Title" private const val TITLE = "Title"
private const val TASK = "Task"
fun newInstance( fun newInstance(
titleId: Int, titleId: Int,
task: () -> Any
): IndeterminateProgressDialogFragment { ): IndeterminateProgressDialogFragment {
val dialog = IndeterminateProgressDialogFragment() val dialog = IndeterminateProgressDialogFragment()
val args = Bundle() val args = Bundle()
args.putInt(TITLE, titleId) args.putInt(TITLE, titleId)
args.putSerializable(TASK, task as Serializable)
dialog.arguments = args dialog.arguments = args
return dialog 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.color.MaterialColors
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.navigation.NavigationBarView import com.google.android.material.navigation.NavigationBarView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -340,44 +339,34 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
File(DirectoryInitialization.userDirectory + "/nand/system/Contents/registered/") File(DirectoryInitialization.userDirectory + "/nand/system/Contents/registered/")
val cacheFirmwareDir = File("${cacheDir.path}/registered/") val cacheFirmwareDir = File("${cacheDir.path}/registered/")
val installingFirmwareDialog = IndeterminateProgressDialogFragment.newInstance( val task: () -> Any = {
R.string.firmware_installing var messageToShow: Any
)
installingFirmwareDialog.isCancelable = false
installingFirmwareDialog.show(supportFragmentManager, IndeterminateProgressDialogFragment.TAG)
lifecycleScope.launch(Dispatchers.IO) {
try { try {
FileUtil.unzip(inputZip, cacheFirmwareDir) FileUtil.unzip(inputZip, cacheFirmwareDir)
val unfilteredNumOfFiles = cacheFirmwareDir.list()?.size ?: -1 val unfilteredNumOfFiles = cacheFirmwareDir.list()?.size ?: -1
val filteredNumOfFiles = cacheFirmwareDir.list(filterNCA)?.size ?: -2 val filteredNumOfFiles = cacheFirmwareDir.list(filterNCA)?.size ?: -2
if (unfilteredNumOfFiles != filteredNumOfFiles) { if (unfilteredNumOfFiles != filteredNumOfFiles) {
withContext(Dispatchers.Main) { messageToShow = MessageDialogFragment.newInstance(
installingFirmwareDialog.dismiss()
MessageDialogFragment.newInstance(
R.string.firmware_installed_failure, R.string.firmware_installed_failure,
R.string.firmware_installed_failure_description R.string.firmware_installed_failure_description
).show(supportFragmentManager, MessageDialogFragment.TAG) )
}
} else { } else {
firmwarePath.deleteRecursively() firmwarePath.deleteRecursively()
cacheFirmwareDir.copyRecursively(firmwarePath, true) cacheFirmwareDir.copyRecursively(firmwarePath, true)
withContext(Dispatchers.Main) { messageToShow = getString(R.string.save_file_imported_success)
installingFirmwareDialog.dismiss()
Toast.makeText(
applicationContext,
getString(R.string.save_file_imported_success),
Toast.LENGTH_LONG
).show()
}
} }
} catch (e: Exception) { } catch (e: Exception) {
Toast.makeText(applicationContext, getString(R.string.fatal_error), Toast.LENGTH_LONG) messageToShow = getString(R.string.fatal_error)
.show()
} finally { } finally {
cacheFirmwareDir.deleteRecursively() cacheFirmwareDir.deleteRecursively()
} }
messageToShow
} }
IndeterminateProgressDialogFragment.newInstance(
R.string.firmware_installing,
task
).show(supportFragmentManager, IndeterminateProgressDialogFragment.TAG)
} }
val getAmiiboKey = val getAmiiboKey =