diff options
| author | 2023-04-28 18:06:01 -0400 | |
|---|---|---|
| committer | 2023-06-03 00:05:56 -0700 | |
| commit | 72247a2324ffe6a37596820e8e4d817076406d0c (patch) | |
| tree | fa7de6711ed3b18fd92a593074cafc6d60767cfa /src/android/app | |
| parent | android: Allow search bar to scroll offscreen (diff) | |
| download | yuzu-72247a2324ffe6a37596820e8e4d817076406d0c.tar.gz yuzu-72247a2324ffe6a37596820e8e4d817076406d0c.tar.xz yuzu-72247a2324ffe6a37596820e8e4d817076406d0c.zip | |
android: Add warnings to setup screens
Diffstat (limited to 'src/android/app')
4 files changed, 149 insertions, 13 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupFragment.kt index 7c8a37855..57bef553a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupFragment.kt | |||
| @@ -14,7 +14,6 @@ import androidx.core.content.ContextCompat | |||
| 14 | import androidx.core.view.ViewCompat | 14 | import androidx.core.view.ViewCompat |
| 15 | import androidx.core.view.WindowInsetsCompat | 15 | import androidx.core.view.WindowInsetsCompat |
| 16 | import androidx.core.view.isVisible | 16 | import androidx.core.view.isVisible |
| 17 | import androidx.core.view.updatePadding | ||
| 18 | import androidx.fragment.app.Fragment | 17 | import androidx.fragment.app.Fragment |
| 19 | import androidx.fragment.app.activityViewModels | 18 | import androidx.fragment.app.activityViewModels |
| 20 | import androidx.navigation.findNavController | 19 | import androidx.navigation.findNavController |
| @@ -38,9 +37,12 @@ class SetupFragment : Fragment() { | |||
| 38 | 37 | ||
| 39 | private lateinit var mainActivity: MainActivity | 38 | private lateinit var mainActivity: MainActivity |
| 40 | 39 | ||
| 40 | private lateinit var hasBeenWarned: BooleanArray | ||
| 41 | |||
| 41 | companion object { | 42 | companion object { |
| 42 | const val KEY_NEXT_VISIBILITY = "NextButtonVisibility" | 43 | const val KEY_NEXT_VISIBILITY = "NextButtonVisibility" |
| 43 | const val KEY_BACK_VISIBILITY = "BackButtonVisibility" | 44 | const val KEY_BACK_VISIBILITY = "BackButtonVisibility" |
| 45 | const val KEY_HAS_BEEN_WARNED = "HasBeenWarned" | ||
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | override fun onCreate(savedInstanceState: Bundle?) { | 48 | override fun onCreate(savedInstanceState: Bundle?) { |
| @@ -84,36 +86,51 @@ class SetupFragment : Fragment() { | |||
| 84 | R.string.welcome_description, | 86 | R.string.welcome_description, |
| 85 | 0, | 87 | 0, |
| 86 | true, | 88 | true, |
| 87 | R.string.get_started | 89 | R.string.get_started, |
| 88 | ) { pageForward() }, | 90 | { pageForward() }, |
| 91 | false | ||
| 92 | ), | ||
| 89 | SetupPage( | 93 | SetupPage( |
| 90 | R.drawable.ic_key, | 94 | R.drawable.ic_key, |
| 91 | R.string.keys, | 95 | R.string.keys, |
| 92 | R.string.keys_description, | 96 | R.string.keys_description, |
| 93 | R.drawable.ic_add, | 97 | R.drawable.ic_add, |
| 94 | true, | 98 | true, |
| 95 | R.string.select_keys | 99 | R.string.select_keys, |
| 96 | ) { mainActivity.getProdKey.launch(arrayOf("*/*")) }, | 100 | { mainActivity.getProdKey.launch(arrayOf("*/*")) }, |
| 101 | true, | ||
| 102 | R.string.install_prod_keys_warning, | ||
| 103 | R.string.install_prod_keys_warning_description, | ||
| 104 | R.string.install_prod_keys_warning_help | ||
| 105 | ), | ||
| 97 | SetupPage( | 106 | SetupPage( |
| 98 | R.drawable.ic_controller, | 107 | R.drawable.ic_controller, |
| 99 | R.string.games, | 108 | R.string.games, |
| 100 | R.string.games_description, | 109 | R.string.games_description, |
| 101 | R.drawable.ic_add, | 110 | R.drawable.ic_add, |
| 102 | true, | 111 | true, |
| 103 | R.string.add_games | 112 | R.string.add_games, |
| 104 | ) { mainActivity.getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) }, | 113 | { mainActivity.getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) }, |
| 114 | true, | ||
| 115 | R.string.add_games_warning, | ||
| 116 | R.string.add_games_warning_description, | ||
| 117 | 0 | ||
| 118 | ), | ||
| 105 | SetupPage( | 119 | SetupPage( |
| 106 | R.drawable.ic_check, | 120 | R.drawable.ic_check, |
| 107 | R.string.done, | 121 | R.string.done, |
| 108 | R.string.done_description, | 122 | R.string.done_description, |
| 109 | R.drawable.ic_arrow_forward, | 123 | R.drawable.ic_arrow_forward, |
| 110 | false, | 124 | false, |
| 111 | R.string.text_continue | 125 | R.string.text_continue, |
| 112 | ) { finishSetup() } | 126 | { finishSetup() }, |
| 127 | false | ||
| 128 | ) | ||
| 113 | ) | 129 | ) |
| 114 | binding.viewPager2.apply { | 130 | binding.viewPager2.apply { |
| 115 | adapter = SetupAdapter(requireActivity() as AppCompatActivity, pages) | 131 | adapter = SetupAdapter(requireActivity() as AppCompatActivity, pages) |
| 116 | offscreenPageLimit = 2 | 132 | offscreenPageLimit = 2 |
| 133 | isUserInputEnabled = false | ||
| 117 | } | 134 | } |
| 118 | 135 | ||
| 119 | binding.viewPager2.registerOnPageChangeCallback(object : OnPageChangeCallback() { | 136 | binding.viewPager2.registerOnPageChangeCallback(object : OnPageChangeCallback() { |
| @@ -138,12 +155,26 @@ class SetupFragment : Fragment() { | |||
| 138 | } | 155 | } |
| 139 | }) | 156 | }) |
| 140 | 157 | ||
| 141 | binding.buttonNext.setOnClickListener { pageForward() } | 158 | binding.buttonNext.setOnClickListener { |
| 159 | val index = binding.viewPager2.currentItem | ||
| 160 | val currentPage = pages[index] | ||
| 161 | if (currentPage.hasWarning && !hasBeenWarned[index]) { | ||
| 162 | SetupWarningDialogFragment.newInstance( | ||
| 163 | currentPage.warningTitleId, | ||
| 164 | currentPage.warningDescriptionId, | ||
| 165 | currentPage.warningHelpLinkId, | ||
| 166 | index | ||
| 167 | ).show(childFragmentManager, SetupWarningDialogFragment.TAG) | ||
| 168 | } else { | ||
| 169 | pageForward() | ||
| 170 | } | ||
| 171 | } | ||
| 142 | binding.buttonBack.setOnClickListener { pageBackward() } | 172 | binding.buttonBack.setOnClickListener { pageBackward() } |
| 143 | 173 | ||
| 144 | if (savedInstanceState != null) { | 174 | if (savedInstanceState != null) { |
| 145 | val nextIsVisible = savedInstanceState.getBoolean(KEY_NEXT_VISIBILITY) | 175 | val nextIsVisible = savedInstanceState.getBoolean(KEY_NEXT_VISIBILITY) |
| 146 | val backIsVisible = savedInstanceState.getBoolean(KEY_BACK_VISIBILITY) | 176 | val backIsVisible = savedInstanceState.getBoolean(KEY_BACK_VISIBILITY) |
| 177 | hasBeenWarned = savedInstanceState.getBooleanArray(KEY_HAS_BEEN_WARNED)!! | ||
| 147 | 178 | ||
| 148 | if (nextIsVisible) { | 179 | if (nextIsVisible) { |
| 149 | binding.buttonNext.visibility = View.VISIBLE | 180 | binding.buttonNext.visibility = View.VISIBLE |
| @@ -151,6 +182,8 @@ class SetupFragment : Fragment() { | |||
| 151 | if (backIsVisible) { | 182 | if (backIsVisible) { |
| 152 | binding.buttonBack.visibility = View.VISIBLE | 183 | binding.buttonBack.visibility = View.VISIBLE |
| 153 | } | 184 | } |
| 185 | } else { | ||
| 186 | hasBeenWarned = BooleanArray(pages.size) | ||
| 154 | } | 187 | } |
| 155 | 188 | ||
| 156 | setInsets() | 189 | setInsets() |
| @@ -160,6 +193,7 @@ class SetupFragment : Fragment() { | |||
| 160 | super.onSaveInstanceState(outState) | 193 | super.onSaveInstanceState(outState) |
| 161 | outState.putBoolean(KEY_NEXT_VISIBILITY, binding.buttonNext.isVisible) | 194 | outState.putBoolean(KEY_NEXT_VISIBILITY, binding.buttonNext.isVisible) |
| 162 | outState.putBoolean(KEY_BACK_VISIBILITY, binding.buttonBack.isVisible) | 195 | outState.putBoolean(KEY_BACK_VISIBILITY, binding.buttonBack.isVisible) |
| 196 | outState.putBooleanArray(KEY_HAS_BEEN_WARNED, hasBeenWarned) | ||
| 163 | } | 197 | } |
| 164 | 198 | ||
| 165 | override fun onDestroyView() { | 199 | override fun onDestroyView() { |
| @@ -201,14 +235,18 @@ class SetupFragment : Fragment() { | |||
| 201 | } | 235 | } |
| 202 | } | 236 | } |
| 203 | 237 | ||
| 204 | private fun pageForward() { | 238 | fun pageForward() { |
| 205 | binding.viewPager2.currentItem = binding.viewPager2.currentItem + 1 | 239 | binding.viewPager2.currentItem = binding.viewPager2.currentItem + 1 |
| 206 | } | 240 | } |
| 207 | 241 | ||
| 208 | private fun pageBackward() { | 242 | fun pageBackward() { |
| 209 | binding.viewPager2.currentItem = binding.viewPager2.currentItem - 1 | 243 | binding.viewPager2.currentItem = binding.viewPager2.currentItem - 1 |
| 210 | } | 244 | } |
| 211 | 245 | ||
| 246 | fun setPageWarned(page: Int) { | ||
| 247 | hasBeenWarned[page] = true | ||
| 248 | } | ||
| 249 | |||
| 212 | private fun setInsets() = | 250 | private fun setInsets() = |
| 213 | ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view: View, windowInsets: WindowInsetsCompat -> | 251 | ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view: View, windowInsets: WindowInsetsCompat -> |
| 214 | val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) | 252 | val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupWarningDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupWarningDialogFragment.kt new file mode 100644 index 000000000..b2c1d54af --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupWarningDialogFragment.kt | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | package org.yuzu.yuzu_emu.fragments | ||
| 5 | |||
| 6 | import android.app.Dialog | ||
| 7 | import android.content.DialogInterface | ||
| 8 | import android.content.Intent | ||
| 9 | import android.net.Uri | ||
| 10 | import android.os.Bundle | ||
| 11 | import androidx.fragment.app.DialogFragment | ||
| 12 | import com.google.android.material.dialog.MaterialAlertDialogBuilder | ||
| 13 | import org.yuzu.yuzu_emu.R | ||
| 14 | |||
| 15 | class SetupWarningDialogFragment : DialogFragment() { | ||
| 16 | private var titleId: Int = 0 | ||
| 17 | private var descriptionId: Int = 0 | ||
| 18 | private var helpLinkId: Int = 0 | ||
| 19 | private var page: Int = 0 | ||
| 20 | |||
| 21 | private lateinit var setupFragment: SetupFragment | ||
| 22 | |||
| 23 | override fun onCreate(savedInstanceState: Bundle?) { | ||
| 24 | super.onCreate(savedInstanceState) | ||
| 25 | titleId = requireArguments().getInt(TITLE) | ||
| 26 | descriptionId = requireArguments().getInt(DESCRIPTION) | ||
| 27 | helpLinkId = requireArguments().getInt(HELP_LINK) | ||
| 28 | page = requireArguments().getInt(PAGE) | ||
| 29 | |||
| 30 | setupFragment = requireParentFragment() as SetupFragment | ||
| 31 | } | ||
| 32 | |||
| 33 | override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { | ||
| 34 | val builder = MaterialAlertDialogBuilder(requireContext()) | ||
| 35 | .setPositiveButton(R.string.warning_skip) { _: DialogInterface?, _: Int -> | ||
| 36 | setupFragment.pageForward() | ||
| 37 | setupFragment.setPageWarned(page) | ||
| 38 | } | ||
| 39 | .setNegativeButton(R.string.warning_cancel, null) | ||
| 40 | |||
| 41 | if (titleId != 0) { | ||
| 42 | builder.setTitle(titleId) | ||
| 43 | } else { | ||
| 44 | builder.setTitle("") | ||
| 45 | } | ||
| 46 | if (descriptionId != 0) { | ||
| 47 | builder.setMessage(descriptionId) | ||
| 48 | } | ||
| 49 | if (helpLinkId != 0) { | ||
| 50 | builder.setNeutralButton(R.string.warning_help) { _: DialogInterface?, _: Int -> | ||
| 51 | val helpLink = resources.getString(R.string.install_prod_keys_warning_help) | ||
| 52 | val intent = Intent(Intent.ACTION_VIEW, Uri.parse(helpLink)) | ||
| 53 | startActivity(intent) | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | return builder.show() | ||
| 58 | } | ||
| 59 | |||
| 60 | companion object { | ||
| 61 | const val TAG = "SetupWarningDialogFragment" | ||
| 62 | |||
| 63 | private const val TITLE = "Title" | ||
| 64 | private const val DESCRIPTION = "Description" | ||
| 65 | private const val HELP_LINK = "HelpLink" | ||
| 66 | private const val PAGE = "Page" | ||
| 67 | |||
| 68 | fun newInstance( | ||
| 69 | titleId: Int, | ||
| 70 | descriptionId: Int, | ||
| 71 | helpLinkId: Int, | ||
| 72 | page: Int | ||
| 73 | ): SetupWarningDialogFragment { | ||
| 74 | val dialog = SetupWarningDialogFragment() | ||
| 75 | val bundle = Bundle() | ||
| 76 | bundle.apply { | ||
| 77 | putInt(TITLE, titleId) | ||
| 78 | putInt(DESCRIPTION, descriptionId) | ||
| 79 | putInt(HELP_LINK, helpLinkId) | ||
| 80 | putInt(PAGE, page) | ||
| 81 | } | ||
| 82 | dialog.arguments = bundle | ||
| 83 | return dialog | ||
| 84 | } | ||
| 85 | } | ||
| 86 | } | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SetupPage.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SetupPage.kt index a8a934552..abe572a02 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SetupPage.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SetupPage.kt | |||
| @@ -10,5 +10,9 @@ data class SetupPage( | |||
| 10 | val buttonIconId: Int, | 10 | val buttonIconId: Int, |
| 11 | val leftAlignedIcon: Boolean, | 11 | val leftAlignedIcon: Boolean, |
| 12 | val buttonTextId: Int, | 12 | val buttonTextId: Int, |
| 13 | val buttonAction: () -> Unit | 13 | val buttonAction: () -> Unit, |
| 14 | val hasWarning: Boolean, | ||
| 15 | val warningTitleId: Int = 0, | ||
| 16 | val warningDescriptionId: Int = 0, | ||
| 17 | val warningHelpLinkId: Int = 0 | ||
| 14 | ) | 18 | ) |
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index b0d766e07..6448a8d3f 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml | |||
| @@ -29,10 +29,18 @@ | |||
| 29 | <string name="home_settings">Settings</string> | 29 | <string name="home_settings">Settings</string> |
| 30 | <string name="add_games">Add Games</string> | 30 | <string name="add_games">Add Games</string> |
| 31 | <string name="add_games_description">Select your games folder</string> | 31 | <string name="add_games_description">Select your games folder</string> |
| 32 | <string name="add_games_warning">Skip selecting games folder?</string> | ||
| 33 | <string name="add_games_warning_description">Games won\'t be displayed in the Games list if a folder isn\'t selected.</string> | ||
| 32 | <string name="home_search_games">Search Games</string> | 34 | <string name="home_search_games">Search Games</string> |
| 33 | <string name="games_dir_selected">Games directory selected</string> | 35 | <string name="games_dir_selected">Games directory selected</string> |
| 34 | <string name="install_prod_keys">Install Prod.keys</string> | 36 | <string name="install_prod_keys">Install Prod.keys</string> |
| 35 | <string name="install_prod_keys_description">Required to decrypt retail games</string> | 37 | <string name="install_prod_keys_description">Required to decrypt retail games</string> |
| 38 | <string name="install_prod_keys_warning">Skip adding keys?</string> | ||
| 39 | <string name="install_prod_keys_warning_description">Valid keys are required to emulate retail games. Only homebrew apps will function if you continue.</string> | ||
| 40 | <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string> | ||
| 41 | <string name="warning_help">Help</string> | ||
| 42 | <string name="warning_skip">Skip</string> | ||
| 43 | <string name="warning_cancel">Cancel</string> | ||
| 36 | <string name="install_amiibo_keys">Install Amiibo Keys</string> | 44 | <string name="install_amiibo_keys">Install Amiibo Keys</string> |
| 37 | <string name="install_amiibo_keys_description">Required to use Amiibo in game</string> | 45 | <string name="install_amiibo_keys_description">Required to use Amiibo in game</string> |
| 38 | <string name="invalid_keys_file">Invalid keys file selected</string> | 46 | <string name="invalid_keys_file">Invalid keys file selected</string> |