forked from suyu/suyu
Attempt to move the unzip coroutine to a ViewModel
This commit is contained in:
parent
72597b8ffe
commit
3733187c14
3 changed files with 94 additions and 27 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 =
|
||||||
|
|
Loading…
Reference in a new issue