|
|
|
@ -19,6 +19,7 @@ import androidx.core.content.ContextCompat |
|
|
|
import androidx.core.view.ViewCompat |
|
|
|
import androidx.core.view.WindowInsetsCompat |
|
|
|
import androidx.core.view.isVisible |
|
|
|
import androidx.core.view.updatePadding |
|
|
|
import androidx.fragment.app.Fragment |
|
|
|
import androidx.fragment.app.activityViewModels |
|
|
|
import androidx.navigation.findNavController |
|
|
|
@ -32,10 +33,13 @@ import org.yuzu.yuzu_emu.adapters.SetupAdapter |
|
|
|
import org.yuzu.yuzu_emu.databinding.FragmentSetupBinding |
|
|
|
import org.yuzu.yuzu_emu.features.settings.model.Settings |
|
|
|
import org.yuzu.yuzu_emu.model.HomeViewModel |
|
|
|
import org.yuzu.yuzu_emu.model.SetupCallback |
|
|
|
import org.yuzu.yuzu_emu.model.SetupPage |
|
|
|
import org.yuzu.yuzu_emu.model.StepState |
|
|
|
import org.yuzu.yuzu_emu.ui.main.MainActivity |
|
|
|
import org.yuzu.yuzu_emu.utils.DirectoryInitialization |
|
|
|
import org.yuzu.yuzu_emu.utils.GameHelper |
|
|
|
import org.yuzu.yuzu_emu.utils.ViewUtils |
|
|
|
|
|
|
|
class SetupFragment : Fragment() { |
|
|
|
private var _binding: FragmentSetupBinding? = null |
|
|
|
@ -112,14 +116,22 @@ class SetupFragment : Fragment() { |
|
|
|
0, |
|
|
|
false, |
|
|
|
R.string.give_permission, |
|
|
|
{ permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) }, |
|
|
|
{ |
|
|
|
notificationCallback = it |
|
|
|
permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) |
|
|
|
}, |
|
|
|
true, |
|
|
|
R.string.notification_warning, |
|
|
|
R.string.notification_warning_description, |
|
|
|
0, |
|
|
|
{ |
|
|
|
NotificationManagerCompat.from(requireContext()) |
|
|
|
if (NotificationManagerCompat.from(requireContext()) |
|
|
|
.areNotificationsEnabled() |
|
|
|
) { |
|
|
|
StepState.COMPLETE |
|
|
|
} else { |
|
|
|
StepState.INCOMPLETE |
|
|
|
} |
|
|
|
} |
|
|
|
) |
|
|
|
) |
|
|
|
@ -133,12 +145,22 @@ class SetupFragment : Fragment() { |
|
|
|
R.drawable.ic_add, |
|
|
|
true, |
|
|
|
R.string.select_keys, |
|
|
|
{ mainActivity.getProdKey.launch(arrayOf("*/*")) }, |
|
|
|
{ |
|
|
|
keyCallback = it |
|
|
|
getProdKey.launch(arrayOf("*/*")) |
|
|
|
}, |
|
|
|
true, |
|
|
|
R.string.install_prod_keys_warning, |
|
|
|
R.string.install_prod_keys_warning_description, |
|
|
|
R.string.install_prod_keys_warning_help, |
|
|
|
{ File(DirectoryInitialization.userDirectory + "/keys/prod.keys").exists() } |
|
|
|
{ |
|
|
|
val file = File(DirectoryInitialization.userDirectory + "/keys/prod.keys") |
|
|
|
if (file.exists()) { |
|
|
|
StepState.COMPLETE |
|
|
|
} else { |
|
|
|
StepState.INCOMPLETE |
|
|
|
} |
|
|
|
} |
|
|
|
) |
|
|
|
) |
|
|
|
add( |
|
|
|
@ -150,9 +172,8 @@ class SetupFragment : Fragment() { |
|
|
|
true, |
|
|
|
R.string.add_games, |
|
|
|
{ |
|
|
|
mainActivity.getGamesDirectory.launch( |
|
|
|
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data |
|
|
|
) |
|
|
|
gamesDirCallback = it |
|
|
|
getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) |
|
|
|
}, |
|
|
|
true, |
|
|
|
R.string.add_games_warning, |
|
|
|
@ -163,7 +184,11 @@ class SetupFragment : Fragment() { |
|
|
|
PreferenceManager.getDefaultSharedPreferences( |
|
|
|
YuzuApplication.appContext |
|
|
|
) |
|
|
|
preferences.getString(GameHelper.KEY_GAME_PATH, "")!!.isNotEmpty() |
|
|
|
if (preferences.getString(GameHelper.KEY_GAME_PATH, "")!!.isNotEmpty()) { |
|
|
|
StepState.COMPLETE |
|
|
|
} else { |
|
|
|
StepState.INCOMPLETE |
|
|
|
} |
|
|
|
} |
|
|
|
) |
|
|
|
) |
|
|
|
@ -181,6 +206,13 @@ class SetupFragment : Fragment() { |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
homeViewModel.shouldPageForward.observe(viewLifecycleOwner) { |
|
|
|
if (it) { |
|
|
|
pageForward() |
|
|
|
homeViewModel.setShouldPageForward(false) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
binding.viewPager2.apply { |
|
|
|
adapter = SetupAdapter(requireActivity() as AppCompatActivity, pages) |
|
|
|
offscreenPageLimit = 2 |
|
|
|
@ -194,15 +226,15 @@ class SetupFragment : Fragment() { |
|
|
|
super.onPageSelected(position) |
|
|
|
|
|
|
|
if (position == 1 && previousPosition == 0) { |
|
|
|
showView(binding.buttonNext) |
|
|
|
showView(binding.buttonBack) |
|
|
|
ViewUtils.showView(binding.buttonNext) |
|
|
|
ViewUtils.showView(binding.buttonBack) |
|
|
|
} else if (position == 0 && previousPosition == 1) { |
|
|
|
hideView(binding.buttonBack) |
|
|
|
hideView(binding.buttonNext) |
|
|
|
ViewUtils.hideView(binding.buttonBack) |
|
|
|
ViewUtils.hideView(binding.buttonNext) |
|
|
|
} else if (position == pages.size - 1 && previousPosition == pages.size - 2) { |
|
|
|
hideView(binding.buttonNext) |
|
|
|
ViewUtils.hideView(binding.buttonNext) |
|
|
|
} else if (position == pages.size - 2 && previousPosition == pages.size - 1) { |
|
|
|
showView(binding.buttonNext) |
|
|
|
ViewUtils.showView(binding.buttonNext) |
|
|
|
} |
|
|
|
|
|
|
|
previousPosition = position |
|
|
|
@ -215,7 +247,8 @@ class SetupFragment : Fragment() { |
|
|
|
|
|
|
|
// Checks if the user has completed the task on the current page |
|
|
|
if (currentPage.hasWarning) { |
|
|
|
if (currentPage.taskCompleted.invoke()) { |
|
|
|
val stepState = currentPage.stepCompleted.invoke() |
|
|
|
if (stepState != StepState.INCOMPLETE) { |
|
|
|
pageForward() |
|
|
|
return@setOnClickListener |
|
|
|
} |
|
|
|
@ -264,9 +297,15 @@ class SetupFragment : Fragment() { |
|
|
|
_binding = null |
|
|
|
} |
|
|
|
|
|
|
|
private lateinit var notificationCallback: SetupCallback |
|
|
|
|
|
|
|
@RequiresApi(Build.VERSION_CODES.TIRAMISU) |
|
|
|
private val permissionLauncher = |
|
|
|
registerForActivityResult(ActivityResultContracts.RequestPermission()) { |
|
|
|
if (it) { |
|
|
|
notificationCallback.onStepCompleted() |
|
|
|
} |
|
|
|
|
|
|
|
if (!it && |
|
|
|
!shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS) |
|
|
|
) { |
|
|
|
@ -277,6 +316,27 @@ class SetupFragment : Fragment() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private lateinit var keyCallback: SetupCallback |
|
|
|
|
|
|
|
val getProdKey = |
|
|
|
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result -> |
|
|
|
if (result != null) { |
|
|
|
if (mainActivity.processKey(result)) { |
|
|
|
keyCallback.onStepCompleted() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private lateinit var gamesDirCallback: SetupCallback |
|
|
|
|
|
|
|
val getGamesDirectory = |
|
|
|
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { result -> |
|
|
|
if (result != null) { |
|
|
|
mainActivity.processGamesDir(result) |
|
|
|
gamesDirCallback.onStepCompleted() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private fun finishSetup() { |
|
|
|
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext).edit() |
|
|
|
.putBoolean(Settings.PREF_FIRST_APP_LAUNCH, false) |
|
|
|
@ -284,33 +344,6 @@ class SetupFragment : Fragment() { |
|
|
|
mainActivity.finishSetup(binding.root.findNavController()) |
|
|
|
} |
|
|
|
|
|
|
|
private fun showView(view: View) { |
|
|
|
view.apply { |
|
|
|
alpha = 0f |
|
|
|
visibility = View.VISIBLE |
|
|
|
isClickable = true |
|
|
|
}.animate().apply { |
|
|
|
duration = 300 |
|
|
|
alpha(1f) |
|
|
|
}.start() |
|
|
|
} |
|
|
|
|
|
|
|
private fun hideView(view: View) { |
|
|
|
if (view.visibility == View.INVISIBLE) { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
view.apply { |
|
|
|
alpha = 1f |
|
|
|
isClickable = false |
|
|
|
}.animate().apply { |
|
|
|
duration = 300 |
|
|
|
alpha(0f) |
|
|
|
}.withEndAction { |
|
|
|
view.visibility = View.INVISIBLE |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fun pageForward() { |
|
|
|
binding.viewPager2.currentItem = binding.viewPager2.currentItem + 1 |
|
|
|
} |
|
|
|
@ -326,15 +359,29 @@ class SetupFragment : Fragment() { |
|
|
|
private fun setInsets() = |
|
|
|
ViewCompat.setOnApplyWindowInsetsListener( |
|
|
|
binding.root |
|
|
|
) { view: View, windowInsets: WindowInsetsCompat -> |
|
|
|
) { _: View, windowInsets: WindowInsetsCompat -> |
|
|
|
val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) |
|
|
|
val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) |
|
|
|
view.setPadding( |
|
|
|
barInsets.left + cutoutInsets.left, |
|
|
|
barInsets.top + cutoutInsets.top, |
|
|
|
barInsets.right + cutoutInsets.right, |
|
|
|
barInsets.bottom + cutoutInsets.bottom |
|
|
|
) |
|
|
|
|
|
|
|
val leftPadding = barInsets.left + cutoutInsets.left |
|
|
|
val topPadding = barInsets.top + cutoutInsets.top |
|
|
|
val rightPadding = barInsets.right + cutoutInsets.right |
|
|
|
val bottomPadding = barInsets.bottom + cutoutInsets.bottom |
|
|
|
|
|
|
|
if (resources.getBoolean(R.bool.small_layout)) { |
|
|
|
binding.viewPager2 |
|
|
|
.updatePadding(left = leftPadding, top = topPadding, right = rightPadding) |
|
|
|
binding.constraintButtons |
|
|
|
.updatePadding(left = leftPadding, right = rightPadding, bottom = bottomPadding) |
|
|
|
} else { |
|
|
|
binding.viewPager2.updatePadding(top = topPadding, bottom = bottomPadding) |
|
|
|
binding.constraintButtons |
|
|
|
.updatePadding( |
|
|
|
left = leftPadding, |
|
|
|
right = rightPadding, |
|
|
|
bottom = bottomPadding |
|
|
|
) |
|
|
|
} |
|
|
|
windowInsets |
|
|
|
} |
|
|
|
} |