mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	Attempt to move the unzip coroutine to a ViewModel
This commit is contained in:
		@@ -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 =
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user