Repository: skyline-emu/skyline
File: app/src/main/java/emu/skyline/AppDialog.kt (Kotlin)

Code before:
/**
 * This dialog is used to show extra game metadata and provide extra options such as pinning the game to the home screen
 */
class AppDialog : BottomSheetDialogFragment() {
    companion object {
        /**
         * @param item This is used to hold the [AppItem] between instances
         */
        fun newInstance(item : AppItem) : AppDialog {
            val args = Bundle()
            args.putSerializable(AppItemTag, item)

            val fragment = AppDialog()
            fragment.arguments = args
            return fragment
        }
    }

    private lateinit var binding : AppDialogBinding

    private val item by lazy { requireArguments().serializable<AppItem>(AppItemTag)!! }

    private val savesFolderRoot by lazy { "${requireContext().getPublicFilesDir().canonicalPath}/switch/nand/user/save/0000000000000000/00000000000000000000000000000001/" }
    private var lastZipCreated : File? = null
    private val documentPicker = registerForActivityResult(ActivityResultContracts.OpenDocument()) {
        it?.let { uri ->
            try {
                val savesFolder = File(savesFolderRoot)
                var inputZip = requireContext().contentResolver.openInputStream(uri)
                var validZip = false
                // A TitleID must be the first folder name inside the zip in order to be considered valid.
                if (inputZip != null) {
                    ZipInputStream(BufferedInputStream(inputZip)).use { zis ->
                        validZip = Regex("^0100[0-9A-Fa-f]{12}/").containsMatchIn(zis.nextEntry.name)
                    }
                }
                inputZip = requireContext().contentResolver.openInputStream(uri)
                if (inputZip != null && validZip){
                    CoroutineScope(Dispatchers.IO).launch {
                        ZipUtils.unzip(inputZip, savesFolder)
                        withContext(Dispatchers.Main){
                            val isSaveFileOfThisGame = File("$savesFolderRoot${item.titleId}").exists()
                            binding.deleteSave.isEnabled = isSaveFileOfThisGame
                            binding.exportSave.isEnabled = isSaveFileOfThisGame
                            Snackbar.make(binding.root, R.string.save_file_imported_ok, Snackbar.LENGTH_LONG).show()
                        }
                    }
                } else {
                    Snackbar.make(binding.root, getString(R.string.save_file_invalid_zip_structure), Snackbar.LENGTH_LONG).show()
                }
            } catch (e: Exception) {

Review comment (suggestion):
Just like the export function, I'd also make an `importSave` function here to avoid having all this logic in a variable that isn't strictly related to it. Also add documentation (KDoc) on both the export and import functions.

Code after:
/**
 * This dialog is used to show extra game metadata and provide extra options such as pinning the game to the home screen
 */
class AppDialog : BottomSheetDialogFragment() {
    companion object {
        /**
         * @param item This is used to hold the [AppItem] between instances
         */
        fun newInstance(item : AppItem) : AppDialog {
            val args = Bundle()
            args.putSerializable(AppItemTag, item)

            val fragment = AppDialog()
            fragment.arguments = args
            return fragment
        }
    }

    private lateinit var binding : AppDialogBinding

    private val item by lazy { requireArguments().serializable<AppItem>(AppItemTag)!! }

    private val savesFolderRoot by lazy { "${requireContext().getPublicFilesDir().canonicalPath}/switch/nand/user/save/0000000000000000/00000000000000000000000000000001/" }
    private var lastZipCreated : File? = null
    private val documentPicker = registerForActivityResult(ActivityResultContracts.OpenDocument()) {
        it?.let { uri -> importSave(uri) }
    }

    /**
     * This inflates the layout of the dialog after initial view creation
     */
    override fun onCreateView(inflater : LayoutInflater, container : ViewGroup?, savedInstanceState : Bundle?) = AppDialogBinding.inflate(inflater).also { binding = it }.root

    override fun onViewCreated(view : View, savedInstanceState : Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // Set the peek height after the root view has been laid out
        view.apply {
            post {
                val behavior = BottomSheetBehavior.from(parent as View)
                behavior.peekHeight = height
            }
        }

        binding.gameIcon.setImageBitmap(item.bitmapIcon)
        binding.gameTitle.text = item.title
        binding.gameVersion.text = item.version ?: item.loaderResultString(requireContext())
        binding.gameTitleId.text = item.titleId
        binding.gameAuthor.text = item.author

        binding.gamePlay.isEnabled = item.loaderResult == LoaderResult.Success