android: Add warnings to setup screens
This commit is contained in:
		| @@ -14,7 +14,6 @@ import androidx.core.content.ContextCompat | |||||||
| import androidx.core.view.ViewCompat | import androidx.core.view.ViewCompat | ||||||
| import androidx.core.view.WindowInsetsCompat | import androidx.core.view.WindowInsetsCompat | ||||||
| import androidx.core.view.isVisible | import androidx.core.view.isVisible | ||||||
| import androidx.core.view.updatePadding |  | ||||||
| import androidx.fragment.app.Fragment | import androidx.fragment.app.Fragment | ||||||
| import androidx.fragment.app.activityViewModels | import androidx.fragment.app.activityViewModels | ||||||
| import androidx.navigation.findNavController | import androidx.navigation.findNavController | ||||||
| @@ -38,9 +37,12 @@ class SetupFragment : Fragment() { | |||||||
|  |  | ||||||
|     private lateinit var mainActivity: MainActivity |     private lateinit var mainActivity: MainActivity | ||||||
|  |  | ||||||
|  |     private lateinit var hasBeenWarned: BooleanArray | ||||||
|  |  | ||||||
|     companion object { |     companion object { | ||||||
|         const val KEY_NEXT_VISIBILITY = "NextButtonVisibility" |         const val KEY_NEXT_VISIBILITY = "NextButtonVisibility" | ||||||
|         const val KEY_BACK_VISIBILITY = "BackButtonVisibility" |         const val KEY_BACK_VISIBILITY = "BackButtonVisibility" | ||||||
|  |         const val KEY_HAS_BEEN_WARNED = "HasBeenWarned" | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun onCreate(savedInstanceState: Bundle?) { |     override fun onCreate(savedInstanceState: Bundle?) { | ||||||
| @@ -84,36 +86,51 @@ class SetupFragment : Fragment() { | |||||||
|                 R.string.welcome_description, |                 R.string.welcome_description, | ||||||
|                 0, |                 0, | ||||||
|                 true, |                 true, | ||||||
|                 R.string.get_started |                 R.string.get_started, | ||||||
|             ) { pageForward() }, |                 { pageForward() }, | ||||||
|  |                 false | ||||||
|  |             ), | ||||||
|             SetupPage( |             SetupPage( | ||||||
|                 R.drawable.ic_key, |                 R.drawable.ic_key, | ||||||
|                 R.string.keys, |                 R.string.keys, | ||||||
|                 R.string.keys_description, |                 R.string.keys_description, | ||||||
|                 R.drawable.ic_add, |                 R.drawable.ic_add, | ||||||
|                 true, |                 true, | ||||||
|                 R.string.select_keys |                 R.string.select_keys, | ||||||
|             ) { mainActivity.getProdKey.launch(arrayOf("*/*")) }, |                 { mainActivity.getProdKey.launch(arrayOf("*/*")) }, | ||||||
|  |                 true, | ||||||
|  |                 R.string.install_prod_keys_warning, | ||||||
|  |                 R.string.install_prod_keys_warning_description, | ||||||
|  |                 R.string.install_prod_keys_warning_help | ||||||
|  |             ), | ||||||
|             SetupPage( |             SetupPage( | ||||||
|                 R.drawable.ic_controller, |                 R.drawable.ic_controller, | ||||||
|                 R.string.games, |                 R.string.games, | ||||||
|                 R.string.games_description, |                 R.string.games_description, | ||||||
|                 R.drawable.ic_add, |                 R.drawable.ic_add, | ||||||
|                 true, |                 true, | ||||||
|                 R.string.add_games |                 R.string.add_games, | ||||||
|             ) { mainActivity.getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) }, |                 { mainActivity.getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) }, | ||||||
|  |                 true, | ||||||
|  |                 R.string.add_games_warning, | ||||||
|  |                 R.string.add_games_warning_description, | ||||||
|  |                 0 | ||||||
|  |             ), | ||||||
|             SetupPage( |             SetupPage( | ||||||
|                 R.drawable.ic_check, |                 R.drawable.ic_check, | ||||||
|                 R.string.done, |                 R.string.done, | ||||||
|                 R.string.done_description, |                 R.string.done_description, | ||||||
|                 R.drawable.ic_arrow_forward, |                 R.drawable.ic_arrow_forward, | ||||||
|                 false, |                 false, | ||||||
|                 R.string.text_continue |                 R.string.text_continue, | ||||||
|             ) { finishSetup() } |                 { finishSetup() }, | ||||||
|  |                 false | ||||||
|  |             ) | ||||||
|         ) |         ) | ||||||
|         binding.viewPager2.apply { |         binding.viewPager2.apply { | ||||||
|             adapter = SetupAdapter(requireActivity() as AppCompatActivity, pages) |             adapter = SetupAdapter(requireActivity() as AppCompatActivity, pages) | ||||||
|             offscreenPageLimit = 2 |             offscreenPageLimit = 2 | ||||||
|  |             isUserInputEnabled = false | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         binding.viewPager2.registerOnPageChangeCallback(object : OnPageChangeCallback() { |         binding.viewPager2.registerOnPageChangeCallback(object : OnPageChangeCallback() { | ||||||
| @@ -138,12 +155,26 @@ class SetupFragment : Fragment() { | |||||||
|             } |             } | ||||||
|         }) |         }) | ||||||
|  |  | ||||||
|         binding.buttonNext.setOnClickListener { pageForward() } |         binding.buttonNext.setOnClickListener { | ||||||
|  |             val index = binding.viewPager2.currentItem | ||||||
|  |             val currentPage = pages[index] | ||||||
|  |             if (currentPage.hasWarning && !hasBeenWarned[index]) { | ||||||
|  |                 SetupWarningDialogFragment.newInstance( | ||||||
|  |                     currentPage.warningTitleId, | ||||||
|  |                     currentPage.warningDescriptionId, | ||||||
|  |                     currentPage.warningHelpLinkId, | ||||||
|  |                     index | ||||||
|  |                 ).show(childFragmentManager, SetupWarningDialogFragment.TAG) | ||||||
|  |             } else { | ||||||
|  |                 pageForward() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|         binding.buttonBack.setOnClickListener { pageBackward() } |         binding.buttonBack.setOnClickListener { pageBackward() } | ||||||
|  |  | ||||||
|         if (savedInstanceState != null) { |         if (savedInstanceState != null) { | ||||||
|             val nextIsVisible = savedInstanceState.getBoolean(KEY_NEXT_VISIBILITY) |             val nextIsVisible = savedInstanceState.getBoolean(KEY_NEXT_VISIBILITY) | ||||||
|             val backIsVisible = savedInstanceState.getBoolean(KEY_BACK_VISIBILITY) |             val backIsVisible = savedInstanceState.getBoolean(KEY_BACK_VISIBILITY) | ||||||
|  |             hasBeenWarned = savedInstanceState.getBooleanArray(KEY_HAS_BEEN_WARNED)!! | ||||||
|  |  | ||||||
|             if (nextIsVisible) { |             if (nextIsVisible) { | ||||||
|                 binding.buttonNext.visibility = View.VISIBLE |                 binding.buttonNext.visibility = View.VISIBLE | ||||||
| @@ -151,6 +182,8 @@ class SetupFragment : Fragment() { | |||||||
|             if (backIsVisible) { |             if (backIsVisible) { | ||||||
|                 binding.buttonBack.visibility = View.VISIBLE |                 binding.buttonBack.visibility = View.VISIBLE | ||||||
|             } |             } | ||||||
|  |         } else { | ||||||
|  |             hasBeenWarned = BooleanArray(pages.size) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         setInsets() |         setInsets() | ||||||
| @@ -160,6 +193,7 @@ class SetupFragment : Fragment() { | |||||||
|         super.onSaveInstanceState(outState) |         super.onSaveInstanceState(outState) | ||||||
|         outState.putBoolean(KEY_NEXT_VISIBILITY, binding.buttonNext.isVisible) |         outState.putBoolean(KEY_NEXT_VISIBILITY, binding.buttonNext.isVisible) | ||||||
|         outState.putBoolean(KEY_BACK_VISIBILITY, binding.buttonBack.isVisible) |         outState.putBoolean(KEY_BACK_VISIBILITY, binding.buttonBack.isVisible) | ||||||
|  |         outState.putBooleanArray(KEY_HAS_BEEN_WARNED, hasBeenWarned) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun onDestroyView() { |     override fun onDestroyView() { | ||||||
| @@ -201,14 +235,18 @@ class SetupFragment : Fragment() { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun pageForward() { |     fun pageForward() { | ||||||
|         binding.viewPager2.currentItem = binding.viewPager2.currentItem + 1 |         binding.viewPager2.currentItem = binding.viewPager2.currentItem + 1 | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun pageBackward() { |     fun pageBackward() { | ||||||
|         binding.viewPager2.currentItem = binding.viewPager2.currentItem - 1 |         binding.viewPager2.currentItem = binding.viewPager2.currentItem - 1 | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fun setPageWarned(page: Int) { | ||||||
|  |         hasBeenWarned[page] = true | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private fun setInsets() = |     private fun setInsets() = | ||||||
|         ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view: View, windowInsets: WindowInsetsCompat -> |         ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view: View, windowInsets: WindowInsetsCompat -> | ||||||
|             val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) |             val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) | ||||||
|   | |||||||
| @@ -0,0 +1,86 @@ | |||||||
|  | // SPDX-FileCopyrightText: 2023 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | package org.yuzu.yuzu_emu.fragments | ||||||
|  |  | ||||||
|  | import android.app.Dialog | ||||||
|  | import android.content.DialogInterface | ||||||
|  | import android.content.Intent | ||||||
|  | import android.net.Uri | ||||||
|  | import android.os.Bundle | ||||||
|  | import androidx.fragment.app.DialogFragment | ||||||
|  | import com.google.android.material.dialog.MaterialAlertDialogBuilder | ||||||
|  | import org.yuzu.yuzu_emu.R | ||||||
|  |  | ||||||
|  | class SetupWarningDialogFragment : DialogFragment() { | ||||||
|  |     private var titleId: Int = 0 | ||||||
|  |     private var descriptionId: Int = 0 | ||||||
|  |     private var helpLinkId: Int = 0 | ||||||
|  |     private var page: Int = 0 | ||||||
|  |  | ||||||
|  |     private lateinit var setupFragment: SetupFragment | ||||||
|  |  | ||||||
|  |     override fun onCreate(savedInstanceState: Bundle?) { | ||||||
|  |         super.onCreate(savedInstanceState) | ||||||
|  |         titleId = requireArguments().getInt(TITLE) | ||||||
|  |         descriptionId = requireArguments().getInt(DESCRIPTION) | ||||||
|  |         helpLinkId = requireArguments().getInt(HELP_LINK) | ||||||
|  |         page = requireArguments().getInt(PAGE) | ||||||
|  |  | ||||||
|  |         setupFragment = requireParentFragment() as SetupFragment | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { | ||||||
|  |         val builder = MaterialAlertDialogBuilder(requireContext()) | ||||||
|  |             .setPositiveButton(R.string.warning_skip) { _: DialogInterface?, _: Int -> | ||||||
|  |                 setupFragment.pageForward() | ||||||
|  |                 setupFragment.setPageWarned(page) | ||||||
|  |             } | ||||||
|  |             .setNegativeButton(R.string.warning_cancel, null) | ||||||
|  |  | ||||||
|  |         if (titleId != 0) { | ||||||
|  |             builder.setTitle(titleId) | ||||||
|  |         } else { | ||||||
|  |             builder.setTitle("") | ||||||
|  |         } | ||||||
|  |         if (descriptionId != 0) { | ||||||
|  |             builder.setMessage(descriptionId) | ||||||
|  |         } | ||||||
|  |         if (helpLinkId != 0) { | ||||||
|  |             builder.setNeutralButton(R.string.warning_help) { _: DialogInterface?, _: Int -> | ||||||
|  |                 val helpLink = resources.getString(R.string.install_prod_keys_warning_help) | ||||||
|  |                 val intent = Intent(Intent.ACTION_VIEW, Uri.parse(helpLink)) | ||||||
|  |                 startActivity(intent) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return builder.show() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     companion object { | ||||||
|  |         const val TAG = "SetupWarningDialogFragment" | ||||||
|  |  | ||||||
|  |         private const val TITLE = "Title" | ||||||
|  |         private const val DESCRIPTION = "Description" | ||||||
|  |         private const val HELP_LINK = "HelpLink" | ||||||
|  |         private const val PAGE = "Page" | ||||||
|  |  | ||||||
|  |         fun newInstance( | ||||||
|  |             titleId: Int, | ||||||
|  |             descriptionId: Int, | ||||||
|  |             helpLinkId: Int, | ||||||
|  |             page: Int | ||||||
|  |         ): SetupWarningDialogFragment { | ||||||
|  |             val dialog = SetupWarningDialogFragment() | ||||||
|  |             val bundle = Bundle() | ||||||
|  |             bundle.apply { | ||||||
|  |                 putInt(TITLE, titleId) | ||||||
|  |                 putInt(DESCRIPTION, descriptionId) | ||||||
|  |                 putInt(HELP_LINK, helpLinkId) | ||||||
|  |                 putInt(PAGE, page) | ||||||
|  |             } | ||||||
|  |             dialog.arguments = bundle | ||||||
|  |             return dialog | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -10,5 +10,9 @@ data class SetupPage( | |||||||
|     val buttonIconId: Int, |     val buttonIconId: Int, | ||||||
|     val leftAlignedIcon: Boolean, |     val leftAlignedIcon: Boolean, | ||||||
|     val buttonTextId: Int, |     val buttonTextId: Int, | ||||||
|     val buttonAction: () -> Unit |     val buttonAction: () -> Unit, | ||||||
|  |     val hasWarning: Boolean, | ||||||
|  |     val warningTitleId: Int = 0, | ||||||
|  |     val warningDescriptionId: Int = 0, | ||||||
|  |     val warningHelpLinkId: Int = 0 | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -29,10 +29,18 @@ | |||||||
|     <string name="home_settings">Settings</string> |     <string name="home_settings">Settings</string> | ||||||
|     <string name="add_games">Add Games</string> |     <string name="add_games">Add Games</string> | ||||||
|     <string name="add_games_description">Select your games folder</string> |     <string name="add_games_description">Select your games folder</string> | ||||||
|  |     <string name="add_games_warning">Skip selecting games folder?</string> | ||||||
|  |     <string name="add_games_warning_description">Games won\'t be displayed in the Games list if a folder isn\'t selected.</string> | ||||||
|     <string name="home_search_games">Search Games</string> |     <string name="home_search_games">Search Games</string> | ||||||
|     <string name="games_dir_selected">Games directory selected</string> |     <string name="games_dir_selected">Games directory selected</string> | ||||||
|     <string name="install_prod_keys">Install Prod.keys</string> |     <string name="install_prod_keys">Install Prod.keys</string> | ||||||
|     <string name="install_prod_keys_description">Required to decrypt retail games</string> |     <string name="install_prod_keys_description">Required to decrypt retail games</string> | ||||||
|  |     <string name="install_prod_keys_warning">Skip adding keys?</string> | ||||||
|  |     <string name="install_prod_keys_warning_description">Valid keys are required to emulate retail games. Only homebrew apps will function if you continue.</string> | ||||||
|  |     <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string> | ||||||
|  |     <string name="warning_help">Help</string> | ||||||
|  |     <string name="warning_skip">Skip</string> | ||||||
|  |     <string name="warning_cancel">Cancel</string> | ||||||
|     <string name="install_amiibo_keys">Install Amiibo Keys</string> |     <string name="install_amiibo_keys">Install Amiibo Keys</string> | ||||||
|     <string name="install_amiibo_keys_description">Required to use Amiibo in game</string> |     <string name="install_amiibo_keys_description">Required to use Amiibo in game</string> | ||||||
|     <string name="invalid_keys_file">Invalid keys file selected</string> |     <string name="invalid_keys_file">Invalid keys file selected</string> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user