summaryrefslogtreecommitdiff
path: root/src/android/app
diff options
context:
space:
mode:
authorGravatar Charles Lombardo2023-04-28 18:06:01 -0400
committerGravatar bunnei2023-06-03 00:05:56 -0700
commit72247a2324ffe6a37596820e8e4d817076406d0c (patch)
treefa7de6711ed3b18fd92a593074cafc6d60767cfa /src/android/app
parentandroid: Allow search bar to scroll offscreen (diff)
downloadyuzu-72247a2324ffe6a37596820e8e4d817076406d0c.tar.gz
yuzu-72247a2324ffe6a37596820e8e4d817076406d0c.tar.xz
yuzu-72247a2324ffe6a37596820e8e4d817076406d0c.zip
android: Add warnings to setup screens
Diffstat (limited to 'src/android/app')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupFragment.kt62
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupWarningDialogFragment.kt86
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SetupPage.kt6
-rw-r--r--src/android/app/src/main/res/values/strings.xml8
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
14import androidx.core.view.ViewCompat 14import androidx.core.view.ViewCompat
15import androidx.core.view.WindowInsetsCompat 15import androidx.core.view.WindowInsetsCompat
16import androidx.core.view.isVisible 16import androidx.core.view.isVisible
17import androidx.core.view.updatePadding
18import androidx.fragment.app.Fragment 17import androidx.fragment.app.Fragment
19import androidx.fragment.app.activityViewModels 18import androidx.fragment.app.activityViewModels
20import androidx.navigation.findNavController 19import 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
4package org.yuzu.yuzu_emu.fragments
5
6import android.app.Dialog
7import android.content.DialogInterface
8import android.content.Intent
9import android.net.Uri
10import android.os.Bundle
11import androidx.fragment.app.DialogFragment
12import com.google.android.material.dialog.MaterialAlertDialogBuilder
13import org.yuzu.yuzu_emu.R
14
15class 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>