diff options
| author | 2024-02-17 21:23:38 -0500 | |
|---|---|---|
| committer | 2024-02-17 23:09:09 -0500 | |
| commit | 35a3c7226a796ae7205753c13924fe0becd8fe60 (patch) | |
| tree | 9b705b44d686b2ca2feac0057ac92404cab4b3e6 /src/android | |
| parent | Merge pull request #13050 from t895/marquee-helper (diff) | |
| download | yuzu-35a3c7226a796ae7205753c13924fe0becd8fe60.tar.gz yuzu-35a3c7226a796ae7205753c13924fe0becd8fe60.tar.xz yuzu-35a3c7226a796ae7205753c13924fe0becd8fe60.zip | |
android: Create lifecycle utility to simplify common StateFlow operations
Diffstat (limited to 'src/android')
20 files changed, 331 insertions, 630 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GamePropertiesAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GamePropertiesAdapter.kt index 017306875..7366e2c77 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GamePropertiesAdapter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GamePropertiesAdapter.kt | |||
| @@ -6,11 +6,7 @@ package org.yuzu.yuzu_emu.adapters | |||
| 6 | import android.view.LayoutInflater | 6 | import android.view.LayoutInflater |
| 7 | import android.view.ViewGroup | 7 | import android.view.ViewGroup |
| 8 | import androidx.core.content.res.ResourcesCompat | 8 | import androidx.core.content.res.ResourcesCompat |
| 9 | import androidx.lifecycle.Lifecycle | ||
| 10 | import androidx.lifecycle.LifecycleOwner | 9 | import androidx.lifecycle.LifecycleOwner |
| 11 | import androidx.lifecycle.lifecycleScope | ||
| 12 | import androidx.lifecycle.repeatOnLifecycle | ||
| 13 | import kotlinx.coroutines.launch | ||
| 14 | import org.yuzu.yuzu_emu.databinding.CardInstallableIconBinding | 10 | import org.yuzu.yuzu_emu.databinding.CardInstallableIconBinding |
| 15 | import org.yuzu.yuzu_emu.databinding.CardSimpleOutlinedBinding | 11 | import org.yuzu.yuzu_emu.databinding.CardSimpleOutlinedBinding |
| 16 | import org.yuzu.yuzu_emu.model.GameProperty | 12 | import org.yuzu.yuzu_emu.model.GameProperty |
| @@ -18,6 +14,7 @@ import org.yuzu.yuzu_emu.model.InstallableProperty | |||
| 18 | import org.yuzu.yuzu_emu.model.SubmenuProperty | 14 | import org.yuzu.yuzu_emu.model.SubmenuProperty |
| 19 | import org.yuzu.yuzu_emu.utils.ViewUtils.marquee | 15 | import org.yuzu.yuzu_emu.utils.ViewUtils.marquee |
| 20 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible | 16 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
| 17 | import org.yuzu.yuzu_emu.utils.collect | ||
| 21 | import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder | 18 | import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder |
| 22 | 19 | ||
| 23 | class GamePropertiesAdapter( | 20 | class GamePropertiesAdapter( |
| @@ -82,11 +79,7 @@ class GamePropertiesAdapter( | |||
| 82 | binding.details.text = submenuProperty.details.invoke() | 79 | binding.details.text = submenuProperty.details.invoke() |
| 83 | } else if (submenuProperty.detailsFlow != null) { | 80 | } else if (submenuProperty.detailsFlow != null) { |
| 84 | binding.details.setVisible(true) | 81 | binding.details.setVisible(true) |
| 85 | viewLifecycle.lifecycleScope.launch { | 82 | submenuProperty.detailsFlow.collect(viewLifecycle) { binding.details.text = it } |
| 86 | viewLifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { | ||
| 87 | submenuProperty.detailsFlow.collect { binding.details.text = it } | ||
| 88 | } | ||
| 89 | } | ||
| 90 | } else { | 83 | } else { |
| 91 | binding.details.setVisible(false) | 84 | binding.details.setVisible(false) |
| 92 | } | 85 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/HomeSettingAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/HomeSettingAdapter.kt index 9234a4901..0bd196673 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/HomeSettingAdapter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/HomeSettingAdapter.kt | |||
| @@ -8,17 +8,14 @@ import android.view.ViewGroup | |||
| 8 | import androidx.appcompat.app.AppCompatActivity | 8 | import androidx.appcompat.app.AppCompatActivity |
| 9 | import androidx.core.content.ContextCompat | 9 | import androidx.core.content.ContextCompat |
| 10 | import androidx.core.content.res.ResourcesCompat | 10 | import androidx.core.content.res.ResourcesCompat |
| 11 | import androidx.lifecycle.Lifecycle | ||
| 12 | import androidx.lifecycle.LifecycleOwner | 11 | import androidx.lifecycle.LifecycleOwner |
| 13 | import androidx.lifecycle.lifecycleScope | ||
| 14 | import androidx.lifecycle.repeatOnLifecycle | ||
| 15 | import kotlinx.coroutines.launch | ||
| 16 | import org.yuzu.yuzu_emu.R | 12 | import org.yuzu.yuzu_emu.R |
| 17 | import org.yuzu.yuzu_emu.databinding.CardHomeOptionBinding | 13 | import org.yuzu.yuzu_emu.databinding.CardHomeOptionBinding |
| 18 | import org.yuzu.yuzu_emu.fragments.MessageDialogFragment | 14 | import org.yuzu.yuzu_emu.fragments.MessageDialogFragment |
| 19 | import org.yuzu.yuzu_emu.model.HomeSetting | 15 | import org.yuzu.yuzu_emu.model.HomeSetting |
| 20 | import org.yuzu.yuzu_emu.utils.ViewUtils.marquee | 16 | import org.yuzu.yuzu_emu.utils.ViewUtils.marquee |
| 21 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible | 17 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
| 18 | import org.yuzu.yuzu_emu.utils.collect | ||
| 22 | import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder | 19 | import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder |
| 23 | 20 | ||
| 24 | class HomeSettingAdapter( | 21 | class HomeSettingAdapter( |
| @@ -59,11 +56,7 @@ class HomeSettingAdapter( | |||
| 59 | binding.optionIcon.alpha = 0.5f | 56 | binding.optionIcon.alpha = 0.5f |
| 60 | } | 57 | } |
| 61 | 58 | ||
| 62 | viewLifecycle.lifecycleScope.launch { | 59 | model.details.collect(viewLifecycle) { updateOptionDetails(it) } |
| 63 | viewLifecycle.repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 64 | model.details.collect { updateOptionDetails(it) } | ||
| 65 | } | ||
| 66 | } | ||
| 67 | binding.optionDetail.marquee() | 60 | binding.optionDetail.marquee() |
| 68 | 61 | ||
| 69 | binding.root.setOnClickListener { onClick(model) } | 62 | binding.root.setOnClickListener { onClick(model) } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/InputProfileDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/InputProfileDialogFragment.kt index 9b24d41c1..1bae593ae 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/InputProfileDialogFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/InputProfileDialogFragment.kt | |||
| @@ -11,16 +11,13 @@ import android.view.ViewGroup | |||
| 11 | import android.widget.Toast | 11 | import android.widget.Toast |
| 12 | import androidx.fragment.app.DialogFragment | 12 | import androidx.fragment.app.DialogFragment |
| 13 | import androidx.fragment.app.activityViewModels | 13 | import androidx.fragment.app.activityViewModels |
| 14 | import androidx.lifecycle.Lifecycle | ||
| 15 | import androidx.lifecycle.lifecycleScope | ||
| 16 | import androidx.lifecycle.repeatOnLifecycle | ||
| 17 | import androidx.recyclerview.widget.LinearLayoutManager | 14 | import androidx.recyclerview.widget.LinearLayoutManager |
| 18 | import com.google.android.material.dialog.MaterialAlertDialogBuilder | 15 | import com.google.android.material.dialog.MaterialAlertDialogBuilder |
| 19 | import kotlinx.coroutines.launch | ||
| 20 | import org.yuzu.yuzu_emu.R | 16 | import org.yuzu.yuzu_emu.R |
| 21 | import org.yuzu.yuzu_emu.databinding.DialogInputProfilesBinding | 17 | import org.yuzu.yuzu_emu.databinding.DialogInputProfilesBinding |
| 22 | import org.yuzu.yuzu_emu.features.settings.model.view.InputProfileSetting | 18 | import org.yuzu.yuzu_emu.features.settings.model.view.InputProfileSetting |
| 23 | import org.yuzu.yuzu_emu.fragments.MessageDialogFragment | 19 | import org.yuzu.yuzu_emu.fragments.MessageDialogFragment |
| 20 | import org.yuzu.yuzu_emu.utils.collect | ||
| 24 | 21 | ||
| 25 | class InputProfileDialogFragment : DialogFragment() { | 22 | class InputProfileDialogFragment : DialogFragment() { |
| 26 | private var position = 0 | 23 | private var position = 0 |
| @@ -110,25 +107,21 @@ class InputProfileDialogFragment : DialogFragment() { | |||
| 110 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | 107 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 111 | super.onViewCreated(view, savedInstanceState) | 108 | super.onViewCreated(view, savedInstanceState) |
| 112 | 109 | ||
| 113 | viewLifecycleOwner.lifecycleScope.launch { | 110 | settingsViewModel.shouldShowDeleteProfileDialog.collect(viewLifecycleOwner) { |
| 114 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 111 | if (it.isNotEmpty()) { |
| 115 | settingsViewModel.shouldShowDeleteProfileDialog.collect { | 112 | MessageDialogFragment.newInstance( |
| 116 | if (it.isNotEmpty()) { | 113 | activity = requireActivity(), |
| 117 | MessageDialogFragment.newInstance( | 114 | titleId = R.string.delete_input_profile, |
| 118 | activity = requireActivity(), | 115 | descriptionId = R.string.delete_input_profile_description, |
| 119 | titleId = R.string.delete_input_profile, | 116 | positiveAction = { |
| 120 | descriptionId = R.string.delete_input_profile_description, | 117 | setting.deleteProfile(it) |
| 121 | positiveAction = { | 118 | settingsViewModel.setReloadListAndNotifyDataset(true) |
| 122 | setting.deleteProfile(it) | 119 | }, |
| 123 | settingsViewModel.setReloadListAndNotifyDataset(true) | 120 | negativeAction = {}, |
| 124 | }, | 121 | negativeButtonTitleId = android.R.string.cancel |
| 125 | negativeAction = {}, | 122 | ).show(parentFragmentManager, MessageDialogFragment.TAG) |
| 126 | negativeButtonTitleId = android.R.string.cancel | 123 | settingsViewModel.setShouldShowDeleteProfileDialog("") |
| 127 | ).show(parentFragmentManager, MessageDialogFragment.TAG) | 124 | dismiss() |
| 128 | settingsViewModel.setShouldShowDeleteProfileDialog("") | ||
| 129 | dismiss() | ||
| 130 | } | ||
| 131 | } | ||
| 132 | } | 125 | } |
| 133 | } | 126 | } |
| 134 | } | 127 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt index 681a18b3b..455b3b5ff 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt | |||
| @@ -13,14 +13,9 @@ import androidx.appcompat.app.AppCompatActivity | |||
| 13 | import androidx.core.view.ViewCompat | 13 | import androidx.core.view.ViewCompat |
| 14 | import androidx.core.view.WindowCompat | 14 | import androidx.core.view.WindowCompat |
| 15 | import androidx.core.view.WindowInsetsCompat | 15 | import androidx.core.view.WindowInsetsCompat |
| 16 | import androidx.lifecycle.Lifecycle | ||
| 17 | import androidx.lifecycle.lifecycleScope | ||
| 18 | import androidx.lifecycle.repeatOnLifecycle | ||
| 19 | import androidx.navigation.fragment.NavHostFragment | 16 | import androidx.navigation.fragment.NavHostFragment |
| 20 | import androidx.navigation.navArgs | 17 | import androidx.navigation.navArgs |
| 21 | import com.google.android.material.color.MaterialColors | 18 | import com.google.android.material.color.MaterialColors |
| 22 | import kotlinx.coroutines.flow.collectLatest | ||
| 23 | import kotlinx.coroutines.launch | ||
| 24 | import org.yuzu.yuzu_emu.NativeLibrary | 19 | import org.yuzu.yuzu_emu.NativeLibrary |
| 25 | import java.io.IOException | 20 | import java.io.IOException |
| 26 | import org.yuzu.yuzu_emu.R | 21 | import org.yuzu.yuzu_emu.R |
| @@ -70,39 +65,23 @@ class SettingsActivity : AppCompatActivity() { | |||
| 70 | ) | 65 | ) |
| 71 | } | 66 | } |
| 72 | 67 | ||
| 73 | lifecycleScope.apply { | 68 | settingsViewModel.shouldRecreate.collect( |
| 74 | launch { | 69 | this, |
| 75 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 70 | resetState = { settingsViewModel.setShouldRecreate(false) } |
| 76 | settingsViewModel.shouldRecreate.collectLatest { | 71 | ) { if (it) recreate() } |
| 77 | if (it) { | 72 | settingsViewModel.shouldNavigateBack.collect( |
| 78 | settingsViewModel.setShouldRecreate(false) | 73 | this, |
| 79 | recreate() | 74 | resetState = { settingsViewModel.setShouldNavigateBack(false) } |
| 80 | } | 75 | ) { if (it) navigateBack() } |
| 81 | } | 76 | settingsViewModel.shouldShowResetSettingsDialog.collect( |
| 82 | } | 77 | this, |
| 83 | } | 78 | resetState = { settingsViewModel.setShouldShowResetSettingsDialog(false) } |
| 84 | launch { | 79 | ) { |
| 85 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 80 | if (it) { |
| 86 | settingsViewModel.shouldNavigateBack.collectLatest { | 81 | ResetSettingsDialogFragment().show( |
| 87 | if (it) { | 82 | supportFragmentManager, |
| 88 | settingsViewModel.setShouldNavigateBack(false) | 83 | ResetSettingsDialogFragment.TAG |
| 89 | navigateBack() | 84 | ) |
| 90 | } | ||
| 91 | } | ||
| 92 | } | ||
| 93 | } | ||
| 94 | launch { | ||
| 95 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 96 | settingsViewModel.shouldShowResetSettingsDialog.collectLatest { | ||
| 97 | if (it) { | ||
| 98 | settingsViewModel.setShouldShowResetSettingsDialog(false) | ||
| 99 | ResetSettingsDialogFragment().show( | ||
| 100 | supportFragmentManager, | ||
| 101 | ResetSettingsDialogFragment.TAG | ||
| 102 | ) | ||
| 103 | } | ||
| 104 | } | ||
| 105 | } | ||
| 106 | } | 85 | } |
| 107 | } | 86 | } |
| 108 | 87 | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsDialogFragment.kt index 5d1ea5d29..a81ff6b1a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsDialogFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsDialogFragment.kt | |||
| @@ -11,12 +11,8 @@ import android.view.View | |||
| 11 | import android.view.ViewGroup | 11 | import android.view.ViewGroup |
| 12 | import androidx.fragment.app.DialogFragment | 12 | import androidx.fragment.app.DialogFragment |
| 13 | import androidx.fragment.app.activityViewModels | 13 | import androidx.fragment.app.activityViewModels |
| 14 | import androidx.lifecycle.Lifecycle | ||
| 15 | import androidx.lifecycle.lifecycleScope | ||
| 16 | import androidx.lifecycle.repeatOnLifecycle | ||
| 17 | import com.google.android.material.dialog.MaterialAlertDialogBuilder | 14 | import com.google.android.material.dialog.MaterialAlertDialogBuilder |
| 18 | import com.google.android.material.slider.Slider | 15 | import com.google.android.material.slider.Slider |
| 19 | import kotlinx.coroutines.launch | ||
| 20 | import org.yuzu.yuzu_emu.R | 16 | import org.yuzu.yuzu_emu.R |
| 21 | import org.yuzu.yuzu_emu.databinding.DialogSliderBinding | 17 | import org.yuzu.yuzu_emu.databinding.DialogSliderBinding |
| 22 | import org.yuzu.yuzu_emu.features.input.NativeInput | 18 | import org.yuzu.yuzu_emu.features.input.NativeInput |
| @@ -29,6 +25,7 @@ import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting | |||
| 29 | import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting | 25 | import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting |
| 30 | import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting | 26 | import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting |
| 31 | import org.yuzu.yuzu_emu.utils.ParamPackage | 27 | import org.yuzu.yuzu_emu.utils.ParamPackage |
| 28 | import org.yuzu.yuzu_emu.utils.collect | ||
| 32 | 29 | ||
| 33 | class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener { | 30 | class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener { |
| 34 | private var type = 0 | 31 | private var type = 0 |
| @@ -169,17 +166,11 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener | |||
| 169 | super.onViewCreated(view, savedInstanceState) | 166 | super.onViewCreated(view, savedInstanceState) |
| 170 | when (type) { | 167 | when (type) { |
| 171 | SettingsItem.TYPE_SLIDER -> { | 168 | SettingsItem.TYPE_SLIDER -> { |
| 172 | viewLifecycleOwner.lifecycleScope.launch { | 169 | settingsViewModel.sliderTextValue.collect(viewLifecycleOwner) { |
| 173 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 170 | sliderBinding.textValue.text = it |
| 174 | settingsViewModel.sliderTextValue.collect { | 171 | } |
| 175 | sliderBinding.textValue.text = it | 172 | settingsViewModel.sliderProgress.collect(viewLifecycleOwner) { |
| 176 | } | 173 | sliderBinding.slider.value = it.toFloat() |
| 177 | } | ||
| 178 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 179 | settingsViewModel.sliderProgress.collect { | ||
| 180 | sliderBinding.slider.value = it.toFloat() | ||
| 181 | } | ||
| 182 | } | ||
| 183 | } | 174 | } |
| 184 | } | 175 | } |
| 185 | } | 176 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt index 0cf944b43..ec16f16c4 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt | |||
| @@ -13,21 +13,17 @@ import androidx.core.view.WindowInsetsCompat | |||
| 13 | import androidx.core.view.updatePadding | 13 | import androidx.core.view.updatePadding |
| 14 | import androidx.fragment.app.Fragment | 14 | import androidx.fragment.app.Fragment |
| 15 | import androidx.fragment.app.activityViewModels | 15 | import androidx.fragment.app.activityViewModels |
| 16 | import androidx.lifecycle.Lifecycle | ||
| 17 | import androidx.lifecycle.lifecycleScope | ||
| 18 | import androidx.lifecycle.repeatOnLifecycle | ||
| 19 | import androidx.navigation.findNavController | 16 | import androidx.navigation.findNavController |
| 20 | import androidx.navigation.fragment.navArgs | 17 | import androidx.navigation.fragment.navArgs |
| 21 | import androidx.recyclerview.widget.LinearLayoutManager | 18 | import androidx.recyclerview.widget.LinearLayoutManager |
| 22 | import com.google.android.material.transition.MaterialSharedAxis | 19 | import com.google.android.material.transition.MaterialSharedAxis |
| 23 | import kotlinx.coroutines.flow.collectLatest | ||
| 24 | import kotlinx.coroutines.launch | ||
| 25 | import org.yuzu.yuzu_emu.R | 20 | import org.yuzu.yuzu_emu.R |
| 26 | import org.yuzu.yuzu_emu.databinding.FragmentSettingsBinding | 21 | import org.yuzu.yuzu_emu.databinding.FragmentSettingsBinding |
| 27 | import org.yuzu.yuzu_emu.features.input.NativeInput | 22 | import org.yuzu.yuzu_emu.features.input.NativeInput |
| 28 | import org.yuzu.yuzu_emu.features.settings.model.Settings | 23 | import org.yuzu.yuzu_emu.features.settings.model.Settings |
| 29 | import org.yuzu.yuzu_emu.fragments.MessageDialogFragment | 24 | import org.yuzu.yuzu_emu.fragments.MessageDialogFragment |
| 30 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins | 25 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins |
| 26 | import org.yuzu.yuzu_emu.utils.collect | ||
| 31 | 27 | ||
| 32 | class SettingsFragment : Fragment() { | 28 | class SettingsFragment : Fragment() { |
| 33 | private lateinit var presenter: SettingsFragmentPresenter | 29 | private lateinit var presenter: SettingsFragmentPresenter |
| @@ -63,8 +59,7 @@ class SettingsFragment : Fragment() { | |||
| 63 | return binding.root | 59 | return binding.root |
| 64 | } | 60 | } |
| 65 | 61 | ||
| 66 | // This is using the correct scope, lint is just acting up | 62 | @SuppressLint("NotifyDataSetChanged") |
| 67 | @SuppressLint("UnsafeRepeatOnLifecycleDetector", "NotifyDataSetChanged") | ||
| 68 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | 63 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 69 | super.onViewCreated(view, savedInstanceState) | 64 | super.onViewCreated(view, savedInstanceState) |
| 70 | settingsAdapter = SettingsAdapter(this, requireContext()) | 65 | settingsAdapter = SettingsAdapter(this, requireContext()) |
| @@ -100,65 +95,37 @@ class SettingsFragment : Fragment() { | |||
| 100 | settingsViewModel.setShouldNavigateBack(true) | 95 | settingsViewModel.setShouldNavigateBack(true) |
| 101 | } | 96 | } |
| 102 | 97 | ||
| 103 | viewLifecycleOwner.lifecycleScope.apply { | 98 | settingsViewModel.shouldReloadSettingsList.collect( |
| 104 | launch { | 99 | viewLifecycleOwner, |
| 105 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 100 | resetState = { settingsViewModel.setShouldReloadSettingsList(false) } |
| 106 | settingsViewModel.shouldReloadSettingsList.collectLatest { | 101 | ) { if (it) presenter.loadSettingsList() } |
| 107 | if (it) { | 102 | settingsViewModel.adapterItemChanged.collect( |
| 108 | settingsViewModel.setShouldReloadSettingsList(false) | 103 | viewLifecycleOwner, |
| 109 | presenter.loadSettingsList() | 104 | resetState = { settingsViewModel.setAdapterItemChanged(-1) } |
| 110 | } | 105 | ) { if (it != -1) settingsAdapter?.notifyItemChanged(it) } |
| 111 | } | 106 | settingsViewModel.datasetChanged.collect( |
| 112 | } | 107 | viewLifecycleOwner, |
| 113 | } | 108 | resetState = { settingsViewModel.setDatasetChanged(false) } |
| 114 | launch { | 109 | ) { if (it) settingsAdapter?.notifyDataSetChanged() } |
| 115 | repeatOnLifecycle(Lifecycle.State.STARTED) { | 110 | settingsViewModel.reloadListAndNotifyDataset.collect( |
| 116 | settingsViewModel.adapterItemChanged.collect { | 111 | viewLifecycleOwner, |
| 117 | if (it != -1) { | 112 | resetState = { settingsViewModel.setReloadListAndNotifyDataset(false) } |
| 118 | settingsAdapter?.notifyItemChanged(it) | 113 | ) { if (it) presenter.loadSettingsList(true) } |
| 119 | settingsViewModel.setAdapterItemChanged(-1) | 114 | settingsViewModel.shouldShowResetInputDialog.collect( |
| 120 | } | 115 | viewLifecycleOwner, |
| 121 | } | 116 | resetState = { settingsViewModel.setShouldShowResetInputDialog(false) } |
| 122 | } | 117 | ) { |
| 123 | } | 118 | if (it) { |
| 124 | launch { | 119 | MessageDialogFragment.newInstance( |
| 125 | repeatOnLifecycle(Lifecycle.State.STARTED) { | 120 | activity = requireActivity(), |
| 126 | settingsViewModel.datasetChanged.collect { | 121 | titleId = R.string.reset_mapping, |
| 127 | if (it) { | 122 | descriptionId = R.string.reset_mapping_description, |
| 128 | settingsAdapter?.notifyDataSetChanged() | 123 | positiveAction = { |
| 129 | settingsViewModel.setDatasetChanged(false) | 124 | NativeInput.resetControllerMappings(getPlayerIndex()) |
| 130 | } | 125 | settingsViewModel.setReloadListAndNotifyDataset(true) |
| 131 | } | 126 | }, |
| 132 | } | 127 | negativeAction = {} |
| 133 | } | 128 | ).show(parentFragmentManager, MessageDialogFragment.TAG) |
| 134 | launch { | ||
| 135 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 136 | settingsViewModel.reloadListAndNotifyDataset.collectLatest { | ||
| 137 | if (it) { | ||
| 138 | settingsViewModel.setReloadListAndNotifyDataset(false) | ||
| 139 | presenter.loadSettingsList(true) | ||
| 140 | } | ||
| 141 | } | ||
| 142 | } | ||
| 143 | } | ||
| 144 | launch { | ||
| 145 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 146 | settingsViewModel.shouldShowResetInputDialog.collectLatest { | ||
| 147 | if (it) { | ||
| 148 | MessageDialogFragment.newInstance( | ||
| 149 | activity = requireActivity(), | ||
| 150 | titleId = R.string.reset_mapping, | ||
| 151 | descriptionId = R.string.reset_mapping_description, | ||
| 152 | positiveAction = { | ||
| 153 | NativeInput.resetControllerMappings(getPlayerIndex()) | ||
| 154 | settingsViewModel.setReloadListAndNotifyDataset(true) | ||
| 155 | }, | ||
| 156 | negativeAction = {} | ||
| 157 | ).show(parentFragmentManager, MessageDialogFragment.TAG) | ||
| 158 | settingsViewModel.setShouldShowResetInputDialog(false) | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | } | 129 | } |
| 163 | } | 130 | } |
| 164 | 131 | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsSearchFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsSearchFragment.kt index c4c1d563a..ed60cf34f 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsSearchFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsSearchFragment.kt | |||
| @@ -15,20 +15,17 @@ import androidx.core.view.updatePadding | |||
| 15 | import androidx.core.widget.doOnTextChanged | 15 | import androidx.core.widget.doOnTextChanged |
| 16 | import androidx.fragment.app.Fragment | 16 | import androidx.fragment.app.Fragment |
| 17 | import androidx.fragment.app.activityViewModels | 17 | import androidx.fragment.app.activityViewModels |
| 18 | import androidx.lifecycle.Lifecycle | ||
| 19 | import androidx.lifecycle.lifecycleScope | ||
| 20 | import androidx.lifecycle.repeatOnLifecycle | ||
| 21 | import androidx.recyclerview.widget.LinearLayoutManager | 18 | import androidx.recyclerview.widget.LinearLayoutManager |
| 22 | import com.google.android.material.divider.MaterialDividerItemDecoration | 19 | import com.google.android.material.divider.MaterialDividerItemDecoration |
| 23 | import com.google.android.material.transition.MaterialSharedAxis | 20 | import com.google.android.material.transition.MaterialSharedAxis |
| 24 | import info.debatty.java.stringsimilarity.Cosine | 21 | import info.debatty.java.stringsimilarity.Cosine |
| 25 | import kotlinx.coroutines.launch | ||
| 26 | import org.yuzu.yuzu_emu.R | 22 | import org.yuzu.yuzu_emu.R |
| 27 | import org.yuzu.yuzu_emu.databinding.FragmentSettingsSearchBinding | 23 | import org.yuzu.yuzu_emu.databinding.FragmentSettingsSearchBinding |
| 28 | import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | 24 | import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem |
| 29 | import org.yuzu.yuzu_emu.utils.NativeConfig | 25 | import org.yuzu.yuzu_emu.utils.NativeConfig |
| 30 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible | 26 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
| 31 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins | 27 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins |
| 28 | import org.yuzu.yuzu_emu.utils.collect | ||
| 32 | 29 | ||
| 33 | class SettingsSearchFragment : Fragment() { | 30 | class SettingsSearchFragment : Fragment() { |
| 34 | private var _binding: FragmentSettingsSearchBinding? = null | 31 | private var _binding: FragmentSettingsSearchBinding? = null |
| @@ -84,14 +81,10 @@ class SettingsSearchFragment : Fragment() { | |||
| 84 | search() | 81 | search() |
| 85 | binding.settingsList.smoothScrollToPosition(0) | 82 | binding.settingsList.smoothScrollToPosition(0) |
| 86 | } | 83 | } |
| 87 | viewLifecycleOwner.lifecycleScope.launch { | 84 | settingsViewModel.shouldReloadSettingsList.collect(viewLifecycleOwner) { |
| 88 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 85 | if (it) { |
| 89 | settingsViewModel.shouldReloadSettingsList.collect { | 86 | settingsViewModel.setShouldReloadSettingsList(false) |
| 90 | if (it) { | 87 | search() |
| 91 | settingsViewModel.setShouldReloadSettingsList(false) | ||
| 92 | search() | ||
| 93 | } | ||
| 94 | } | ||
| 95 | } | 88 | } |
| 96 | } | 89 | } |
| 97 | 90 | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AddonsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AddonsFragment.kt index 872553ac4..110aa2960 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AddonsFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AddonsFragment.kt | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | package org.yuzu.yuzu_emu.fragments | 4 | package org.yuzu.yuzu_emu.fragments |
| 5 | 5 | ||
| 6 | import android.annotation.SuppressLint | ||
| 7 | import android.content.Intent | 6 | import android.content.Intent |
| 8 | import android.os.Bundle | 7 | import android.os.Bundle |
| 9 | import android.view.LayoutInflater | 8 | import android.view.LayoutInflater |
| @@ -16,9 +15,6 @@ import androidx.core.view.updatePadding | |||
| 16 | import androidx.documentfile.provider.DocumentFile | 15 | import androidx.documentfile.provider.DocumentFile |
| 17 | import androidx.fragment.app.Fragment | 16 | import androidx.fragment.app.Fragment |
| 18 | import androidx.fragment.app.activityViewModels | 17 | import androidx.fragment.app.activityViewModels |
| 19 | import androidx.lifecycle.Lifecycle | ||
| 20 | import androidx.lifecycle.lifecycleScope | ||
| 21 | import androidx.lifecycle.repeatOnLifecycle | ||
| 22 | import androidx.navigation.findNavController | 18 | import androidx.navigation.findNavController |
| 23 | import androidx.navigation.fragment.navArgs | 19 | import androidx.navigation.fragment.navArgs |
| 24 | import androidx.recyclerview.widget.LinearLayoutManager | 20 | import androidx.recyclerview.widget.LinearLayoutManager |
| @@ -32,6 +28,7 @@ import org.yuzu.yuzu_emu.model.HomeViewModel | |||
| 32 | import org.yuzu.yuzu_emu.utils.AddonUtil | 28 | import org.yuzu.yuzu_emu.utils.AddonUtil |
| 33 | import org.yuzu.yuzu_emu.utils.FileUtil.copyFilesTo | 29 | import org.yuzu.yuzu_emu.utils.FileUtil.copyFilesTo |
| 34 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins | 30 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins |
| 31 | import org.yuzu.yuzu_emu.utils.collect | ||
| 35 | import java.io.File | 32 | import java.io.File |
| 36 | 33 | ||
| 37 | class AddonsFragment : Fragment() { | 34 | class AddonsFragment : Fragment() { |
| @@ -60,8 +57,6 @@ class AddonsFragment : Fragment() { | |||
| 60 | return binding.root | 57 | return binding.root |
| 61 | } | 58 | } |
| 62 | 59 | ||
| 63 | // This is using the correct scope, lint is just acting up | ||
| 64 | @SuppressLint("UnsafeRepeatOnLifecycleDetector") | ||
| 65 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | 60 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 66 | super.onViewCreated(view, savedInstanceState) | 61 | super.onViewCreated(view, savedInstanceState) |
| 67 | homeViewModel.setNavigationVisibility(visible = false, animated = false) | 62 | homeViewModel.setNavigationVisibility(visible = false, animated = false) |
| @@ -78,57 +73,41 @@ class AddonsFragment : Fragment() { | |||
| 78 | adapter = AddonAdapter(addonViewModel) | 73 | adapter = AddonAdapter(addonViewModel) |
| 79 | } | 74 | } |
| 80 | 75 | ||
| 81 | viewLifecycleOwner.lifecycleScope.apply { | 76 | addonViewModel.addonList.collect(viewLifecycleOwner) { |
| 82 | launch { | 77 | (binding.listAddons.adapter as AddonAdapter).submitList(it) |
| 83 | repeatOnLifecycle(Lifecycle.State.STARTED) { | 78 | } |
| 84 | addonViewModel.addonList.collect { | 79 | addonViewModel.showModInstallPicker.collect( |
| 85 | (binding.listAddons.adapter as AddonAdapter).submitList(it) | 80 | viewLifecycleOwner, |
| 86 | } | 81 | resetState = { addonViewModel.showModInstallPicker(false) } |
| 87 | } | 82 | ) { if (it) installAddon.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) } |
| 88 | } | 83 | addonViewModel.showModNoticeDialog.collect( |
| 89 | launch { | 84 | viewLifecycleOwner, |
| 90 | repeatOnLifecycle(Lifecycle.State.STARTED) { | 85 | resetState = { addonViewModel.showModNoticeDialog(false) } |
| 91 | addonViewModel.showModInstallPicker.collect { | 86 | ) { |
| 92 | if (it) { | 87 | if (it) { |
| 93 | installAddon.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) | 88 | MessageDialogFragment.newInstance( |
| 94 | addonViewModel.showModInstallPicker(false) | 89 | requireActivity(), |
| 95 | } | 90 | titleId = R.string.addon_notice, |
| 96 | } | 91 | descriptionId = R.string.addon_notice_description, |
| 97 | } | 92 | dismissible = false, |
| 98 | } | 93 | positiveAction = { addonViewModel.showModInstallPicker(true) }, |
| 99 | launch { | 94 | negativeAction = {}, |
| 100 | repeatOnLifecycle(Lifecycle.State.STARTED) { | 95 | negativeButtonTitleId = R.string.close |
| 101 | addonViewModel.showModNoticeDialog.collect { | 96 | ).show(parentFragmentManager, MessageDialogFragment.TAG) |
| 102 | if (it) { | ||
| 103 | MessageDialogFragment.newInstance( | ||
| 104 | requireActivity(), | ||
| 105 | titleId = R.string.addon_notice, | ||
| 106 | descriptionId = R.string.addon_notice_description, | ||
| 107 | dismissible = false, | ||
| 108 | positiveAction = { addonViewModel.showModInstallPicker(true) }, | ||
| 109 | negativeAction = {}, | ||
| 110 | negativeButtonTitleId = R.string.close | ||
| 111 | ).show(parentFragmentManager, MessageDialogFragment.TAG) | ||
| 112 | addonViewModel.showModNoticeDialog(false) | ||
| 113 | } | ||
| 114 | } | ||
| 115 | } | ||
| 116 | } | 97 | } |
| 117 | launch { | 98 | } |
| 118 | repeatOnLifecycle(Lifecycle.State.STARTED) { | 99 | addonViewModel.addonToDelete.collect( |
| 119 | addonViewModel.addonToDelete.collect { | 100 | viewLifecycleOwner, |
| 120 | if (it != null) { | 101 | resetState = { addonViewModel.setAddonToDelete(null) } |
| 121 | MessageDialogFragment.newInstance( | 102 | ) { |
| 122 | requireActivity(), | 103 | if (it != null) { |
| 123 | titleId = R.string.confirm_uninstall, | 104 | MessageDialogFragment.newInstance( |
| 124 | descriptionId = R.string.confirm_uninstall_description, | 105 | requireActivity(), |
| 125 | positiveAction = { addonViewModel.onDeleteAddon(it) }, | 106 | titleId = R.string.confirm_uninstall, |
| 126 | negativeAction = {} | 107 | descriptionId = R.string.confirm_uninstall_description, |
| 127 | ).show(parentFragmentManager, MessageDialogFragment.TAG) | 108 | positiveAction = { addonViewModel.onDeleteAddon(it) }, |
| 128 | addonViewModel.setAddonToDelete(null) | 109 | negativeAction = {} |
| 129 | } | 110 | ).show(parentFragmentManager, MessageDialogFragment.TAG) |
| 130 | } | ||
| 131 | } | ||
| 132 | } | 111 | } |
| 133 | } | 112 | } |
| 134 | 113 | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt index 41cff46c1..8b23a1021 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | package org.yuzu.yuzu_emu.fragments | 4 | package org.yuzu.yuzu_emu.fragments |
| 5 | 5 | ||
| 6 | import android.annotation.SuppressLint | ||
| 7 | import android.os.Bundle | 6 | import android.os.Bundle |
| 8 | import android.view.LayoutInflater | 7 | import android.view.LayoutInflater |
| 9 | import android.view.View | 8 | import android.view.View |
| @@ -14,9 +13,6 @@ import androidx.core.view.WindowInsetsCompat | |||
| 14 | import androidx.core.view.updatePadding | 13 | import androidx.core.view.updatePadding |
| 15 | import androidx.fragment.app.Fragment | 14 | import androidx.fragment.app.Fragment |
| 16 | import androidx.fragment.app.activityViewModels | 15 | import androidx.fragment.app.activityViewModels |
| 17 | import androidx.lifecycle.Lifecycle | ||
| 18 | import androidx.lifecycle.lifecycleScope | ||
| 19 | import androidx.lifecycle.repeatOnLifecycle | ||
| 20 | import androidx.navigation.findNavController | 16 | import androidx.navigation.findNavController |
| 21 | import androidx.navigation.fragment.navArgs | 17 | import androidx.navigation.fragment.navArgs |
| 22 | import androidx.recyclerview.widget.GridLayoutManager | 18 | import androidx.recyclerview.widget.GridLayoutManager |
| @@ -35,6 +31,7 @@ import org.yuzu.yuzu_emu.utils.FileUtil | |||
| 35 | import org.yuzu.yuzu_emu.utils.GpuDriverHelper | 31 | import org.yuzu.yuzu_emu.utils.GpuDriverHelper |
| 36 | import org.yuzu.yuzu_emu.utils.NativeConfig | 32 | import org.yuzu.yuzu_emu.utils.NativeConfig |
| 37 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins | 33 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins |
| 34 | import org.yuzu.yuzu_emu.utils.collect | ||
| 38 | import java.io.File | 35 | import java.io.File |
| 39 | import java.io.IOException | 36 | import java.io.IOException |
| 40 | 37 | ||
| @@ -63,8 +60,6 @@ class DriverManagerFragment : Fragment() { | |||
| 63 | return binding.root | 60 | return binding.root |
| 64 | } | 61 | } |
| 65 | 62 | ||
| 66 | // This is using the correct scope, lint is just acting up | ||
| 67 | @SuppressLint("UnsafeRepeatOnLifecycleDetector") | ||
| 68 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | 63 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 69 | super.onViewCreated(view, savedInstanceState) | 64 | super.onViewCreated(view, savedInstanceState) |
| 70 | homeViewModel.setNavigationVisibility(visible = false, animated = true) | 65 | homeViewModel.setNavigationVisibility(visible = false, animated = true) |
| @@ -89,15 +84,8 @@ class DriverManagerFragment : Fragment() { | |||
| 89 | } | 84 | } |
| 90 | } | 85 | } |
| 91 | 86 | ||
| 92 | viewLifecycleOwner.lifecycleScope.apply { | 87 | driverViewModel.showClearButton.collect(viewLifecycleOwner) { |
| 93 | launch { | 88 | binding.toolbarDrivers.menu.findItem(R.id.menu_driver_use_global).isVisible = it |
| 94 | repeatOnLifecycle(Lifecycle.State.STARTED) { | ||
| 95 | driverViewModel.showClearButton.collect { | ||
| 96 | binding.toolbarDrivers.menu | ||
| 97 | .findItem(R.id.menu_driver_use_global).isVisible = it | ||
| 98 | } | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } | 89 | } |
| 102 | } | 90 | } |
| 103 | 91 | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriversLoadingDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriversLoadingDialogFragment.kt index 6a47b29f0..bad56e434 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriversLoadingDialogFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriversLoadingDialogFragment.kt | |||
| @@ -10,14 +10,11 @@ import android.view.View | |||
| 10 | import android.view.ViewGroup | 10 | import android.view.ViewGroup |
| 11 | import androidx.fragment.app.DialogFragment | 11 | import androidx.fragment.app.DialogFragment |
| 12 | import androidx.fragment.app.activityViewModels | 12 | import androidx.fragment.app.activityViewModels |
| 13 | import androidx.lifecycle.Lifecycle | ||
| 14 | import androidx.lifecycle.lifecycleScope | ||
| 15 | import androidx.lifecycle.repeatOnLifecycle | ||
| 16 | import com.google.android.material.dialog.MaterialAlertDialogBuilder | 13 | import com.google.android.material.dialog.MaterialAlertDialogBuilder |
| 17 | import kotlinx.coroutines.launch | ||
| 18 | import org.yuzu.yuzu_emu.R | 14 | import org.yuzu.yuzu_emu.R |
| 19 | import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding | 15 | import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding |
| 20 | import org.yuzu.yuzu_emu.model.DriverViewModel | 16 | import org.yuzu.yuzu_emu.model.DriverViewModel |
| 17 | import org.yuzu.yuzu_emu.utils.collect | ||
| 21 | 18 | ||
| 22 | class DriversLoadingDialogFragment : DialogFragment() { | 19 | class DriversLoadingDialogFragment : DialogFragment() { |
| 23 | private val driverViewModel: DriverViewModel by activityViewModels() | 20 | private val driverViewModel: DriverViewModel by activityViewModels() |
| @@ -44,13 +41,7 @@ class DriversLoadingDialogFragment : DialogFragment() { | |||
| 44 | 41 | ||
| 45 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | 42 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 46 | super.onViewCreated(view, savedInstanceState) | 43 | super.onViewCreated(view, savedInstanceState) |
| 47 | viewLifecycleOwner.lifecycleScope.apply { | 44 | driverViewModel.isInteractionAllowed.collect(viewLifecycleOwner) { if (it) dismiss() } |
| 48 | launch { | ||
| 49 | repeatOnLifecycle(Lifecycle.State.RESUMED) { | ||
| 50 | driverViewModel.isInteractionAllowed.collect { if (it) dismiss() } | ||
| 51 | } | ||
| 52 | } | ||
| 53 | } | ||
| 54 | } | 45 | } |
| 55 | 46 | ||
| 56 | companion object { | 47 | companion object { |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt index aedc128d6..c3b2b11f8 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt | |||
| @@ -32,9 +32,6 @@ import androidx.drawerlayout.widget.DrawerLayout | |||
| 32 | import androidx.drawerlayout.widget.DrawerLayout.DrawerListener | 32 | import androidx.drawerlayout.widget.DrawerLayout.DrawerListener |
| 33 | import androidx.fragment.app.Fragment | 33 | import androidx.fragment.app.Fragment |
| 34 | import androidx.fragment.app.activityViewModels | 34 | import androidx.fragment.app.activityViewModels |
| 35 | import androidx.lifecycle.Lifecycle | ||
| 36 | import androidx.lifecycle.lifecycleScope | ||
| 37 | import androidx.lifecycle.repeatOnLifecycle | ||
| 38 | import androidx.navigation.findNavController | 35 | import androidx.navigation.findNavController |
| 39 | import androidx.navigation.fragment.navArgs | 36 | import androidx.navigation.fragment.navArgs |
| 40 | import androidx.window.layout.FoldingFeature | 37 | import androidx.window.layout.FoldingFeature |
| @@ -42,9 +39,6 @@ import androidx.window.layout.WindowInfoTracker | |||
| 42 | import androidx.window.layout.WindowLayoutInfo | 39 | import androidx.window.layout.WindowLayoutInfo |
| 43 | import com.google.android.material.dialog.MaterialAlertDialogBuilder | 40 | import com.google.android.material.dialog.MaterialAlertDialogBuilder |
| 44 | import com.google.android.material.slider.Slider | 41 | import com.google.android.material.slider.Slider |
| 45 | import kotlinx.coroutines.Dispatchers | ||
| 46 | import kotlinx.coroutines.flow.collectLatest | ||
| 47 | import kotlinx.coroutines.launch | ||
| 48 | import org.yuzu.yuzu_emu.HomeNavigationDirections | 42 | import org.yuzu.yuzu_emu.HomeNavigationDirections |
| 49 | import org.yuzu.yuzu_emu.NativeLibrary | 43 | import org.yuzu.yuzu_emu.NativeLibrary |
| 50 | import org.yuzu.yuzu_emu.R | 44 | import org.yuzu.yuzu_emu.R |
| @@ -91,14 +85,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 91 | if (context is EmulationActivity) { | 85 | if (context is EmulationActivity) { |
| 92 | emulationActivity = context | 86 | emulationActivity = context |
| 93 | NativeLibrary.setEmulationActivity(context) | 87 | NativeLibrary.setEmulationActivity(context) |
| 94 | |||
| 95 | lifecycleScope.launch(Dispatchers.Main) { | ||
| 96 | lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { | ||
| 97 | WindowInfoTracker.getOrCreate(context) | ||
| 98 | .windowLayoutInfo(context) | ||
| 99 | .collect { updateFoldableLayout(context, it) } | ||
| 100 | } | ||
| 101 | } | ||
| 102 | } else { | 88 | } else { |
| 103 | throw IllegalStateException("EmulationFragment must have EmulationActivity parent") | 89 | throw IllegalStateException("EmulationFragment must have EmulationActivity parent") |
| 104 | } | 90 | } |
| @@ -169,8 +155,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 169 | return binding.root | 155 | return binding.root |
| 170 | } | 156 | } |
| 171 | 157 | ||
| 172 | // This is using the correct scope, lint is just acting up | ||
| 173 | @SuppressLint("UnsafeRepeatOnLifecycleDetector") | ||
| 174 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | 158 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 175 | super.onViewCreated(view, savedInstanceState) | 159 | super.onViewCreated(view, savedInstanceState) |
| 176 | if (requireActivity().isFinishing) { | 160 | if (requireActivity().isFinishing) { |
| @@ -351,129 +335,86 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 351 | binding.loadingTitle.isSelected = true | 335 | binding.loadingTitle.isSelected = true |
| 352 | binding.loadingText.isSelected = true | 336 | binding.loadingText.isSelected = true |
| 353 | 337 | ||
| 354 | viewLifecycleOwner.lifecycleScope.apply { | 338 | WindowInfoTracker.getOrCreate(requireContext()) |
| 355 | launch { | 339 | .windowLayoutInfo(requireActivity()).collect(viewLifecycleOwner) { |
| 356 | repeatOnLifecycle(Lifecycle.State.STARTED) { | 340 | updateFoldableLayout(requireActivity() as EmulationActivity, it) |
| 357 | WindowInfoTracker.getOrCreate(requireContext()) | ||
| 358 | .windowLayoutInfo(requireActivity()) | ||
| 359 | .collect { | ||
| 360 | updateFoldableLayout(requireActivity() as EmulationActivity, it) | ||
| 361 | } | ||
| 362 | } | ||
| 363 | } | 341 | } |
| 364 | launch { | 342 | emulationViewModel.shaderProgress.collect(viewLifecycleOwner) { |
| 365 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 343 | if (it > 0 && it != emulationViewModel.totalShaders.value) { |
| 366 | emulationViewModel.shaderProgress.collectLatest { | 344 | binding.loadingProgressIndicator.isIndeterminate = false |
| 367 | if (it > 0 && it != emulationViewModel.totalShaders.value) { | ||
| 368 | binding.loadingProgressIndicator.isIndeterminate = false | ||
| 369 | |||
| 370 | if (it < binding.loadingProgressIndicator.max) { | ||
| 371 | binding.loadingProgressIndicator.progress = it | ||
| 372 | } | ||
| 373 | } | ||
| 374 | 345 | ||
| 375 | if (it == emulationViewModel.totalShaders.value) { | 346 | if (it < binding.loadingProgressIndicator.max) { |
| 376 | binding.loadingText.setText(R.string.loading) | 347 | binding.loadingProgressIndicator.progress = it |
| 377 | binding.loadingProgressIndicator.isIndeterminate = true | ||
| 378 | } | ||
| 379 | } | ||
| 380 | } | ||
| 381 | } | ||
| 382 | launch { | ||
| 383 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 384 | emulationViewModel.totalShaders.collectLatest { | ||
| 385 | binding.loadingProgressIndicator.max = it | ||
| 386 | } | ||
| 387 | } | 348 | } |
| 388 | } | 349 | } |
| 389 | launch { | 350 | |
| 390 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 351 | if (it == emulationViewModel.totalShaders.value) { |
| 391 | emulationViewModel.shaderMessage.collectLatest { | 352 | binding.loadingText.setText(R.string.loading) |
| 392 | if (it.isNotEmpty()) { | 353 | binding.loadingProgressIndicator.isIndeterminate = true |
| 393 | binding.loadingText.text = it | ||
| 394 | } | ||
| 395 | } | ||
| 396 | } | ||
| 397 | } | 354 | } |
| 398 | launch { | 355 | } |
| 399 | repeatOnLifecycle(Lifecycle.State.RESUMED) { | 356 | emulationViewModel.totalShaders.collect(viewLifecycleOwner) { |
| 400 | driverViewModel.isInteractionAllowed.collect { | 357 | binding.loadingProgressIndicator.max = it |
| 401 | if (it) { | 358 | } |
| 402 | startEmulation() | 359 | emulationViewModel.shaderMessage.collect(viewLifecycleOwner) { |
| 403 | } | 360 | if (it.isNotEmpty()) { |
| 404 | } | 361 | binding.loadingText.text = it |
| 405 | } | ||
| 406 | } | 362 | } |
| 407 | launch { | 363 | } |
| 408 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 364 | |
| 409 | emulationViewModel.emulationStarted.collectLatest { | 365 | emulationViewModel.emulationStarted.collect(viewLifecycleOwner) { |
| 410 | if (it) { | 366 | if (it) { |
| 411 | binding.drawerLayout.setDrawerLockMode(IntSetting.LOCK_DRAWER.getInt()) | 367 | binding.drawerLayout.setDrawerLockMode(IntSetting.LOCK_DRAWER.getInt()) |
| 412 | ViewUtils.showView(binding.surfaceInputOverlay) | 368 | ViewUtils.showView(binding.surfaceInputOverlay) |
| 413 | ViewUtils.hideView(binding.loadingIndicator) | 369 | ViewUtils.hideView(binding.loadingIndicator) |
| 414 | 370 | ||
| 415 | emulationState.updateSurface() | 371 | emulationState.updateSurface() |
| 416 | 372 | ||
| 417 | // Setup overlays | 373 | // Setup overlays |
| 418 | updateShowFpsOverlay() | 374 | updateShowFpsOverlay() |
| 419 | updateThermalOverlay() | 375 | updateThermalOverlay() |
| 420 | } | ||
| 421 | } | ||
| 422 | } | ||
| 423 | } | 376 | } |
| 424 | launch { | 377 | } |
| 425 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 378 | emulationViewModel.isEmulationStopping.collect(viewLifecycleOwner) { |
| 426 | emulationViewModel.isEmulationStopping.collectLatest { | 379 | if (it) { |
| 427 | if (it) { | 380 | binding.loadingText.setText(R.string.shutting_down) |
| 428 | binding.loadingText.setText(R.string.shutting_down) | 381 | ViewUtils.showView(binding.loadingIndicator) |
| 429 | ViewUtils.showView(binding.loadingIndicator) | 382 | ViewUtils.hideView(binding.inputContainer) |
| 430 | ViewUtils.hideView(binding.inputContainer) | 383 | ViewUtils.hideView(binding.showFpsText) |
| 431 | ViewUtils.hideView(binding.showFpsText) | ||
| 432 | } | ||
| 433 | } | ||
| 434 | } | ||
| 435 | } | 384 | } |
| 436 | launch { | 385 | } |
| 437 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 386 | emulationViewModel.drawerOpen.collect(viewLifecycleOwner) { |
| 438 | emulationViewModel.drawerOpen.collect { | 387 | if (it) { |
| 439 | if (it) { | 388 | binding.drawerLayout.open() |
| 440 | binding.drawerLayout.open() | 389 | binding.inGameMenu.requestFocus() |
| 441 | binding.inGameMenu.requestFocus() | 390 | } else { |
| 442 | } else { | 391 | binding.drawerLayout.close() |
| 443 | binding.drawerLayout.close() | ||
| 444 | } | ||
| 445 | } | ||
| 446 | } | ||
| 447 | } | 392 | } |
| 448 | launch { | 393 | } |
| 449 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 394 | emulationViewModel.programChanged.collect(viewLifecycleOwner) { |
| 450 | emulationViewModel.programChanged.collect { | 395 | if (it != 0) { |
| 451 | if (it != 0) { | 396 | emulationViewModel.setEmulationStarted(false) |
| 452 | emulationViewModel.setEmulationStarted(false) | 397 | binding.drawerLayout.close() |
| 453 | binding.drawerLayout.close() | 398 | binding.drawerLayout |
| 454 | binding.drawerLayout | 399 | .setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) |
| 455 | .setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) | 400 | ViewUtils.hideView(binding.surfaceInputOverlay) |
| 456 | ViewUtils.hideView(binding.surfaceInputOverlay) | 401 | ViewUtils.showView(binding.loadingIndicator) |
| 457 | ViewUtils.showView(binding.loadingIndicator) | ||
| 458 | } | ||
| 459 | } | ||
| 460 | } | ||
| 461 | } | 402 | } |
| 462 | launch { | 403 | } |
| 463 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 404 | emulationViewModel.emulationStopped.collect(viewLifecycleOwner) { |
| 464 | emulationViewModel.emulationStopped.collect { | 405 | if (it && emulationViewModel.programChanged.value != -1) { |
| 465 | if (it && emulationViewModel.programChanged.value != -1) { | 406 | if (perfStatsUpdater != null) { |
| 466 | if (perfStatsUpdater != null) { | 407 | perfStatsUpdateHandler.removeCallbacks(perfStatsUpdater!!) |
| 467 | perfStatsUpdateHandler.removeCallbacks(perfStatsUpdater!!) | ||
| 468 | } | ||
| 469 | emulationState.changeProgram(emulationViewModel.programChanged.value) | ||
| 470 | emulationViewModel.setProgramChanged(-1) | ||
| 471 | emulationViewModel.setEmulationStopped(false) | ||
| 472 | } | ||
| 473 | } | ||
| 474 | } | 408 | } |
| 409 | emulationState.changeProgram(emulationViewModel.programChanged.value) | ||
| 410 | emulationViewModel.setProgramChanged(-1) | ||
| 411 | emulationViewModel.setEmulationStopped(false) | ||
| 475 | } | 412 | } |
| 476 | } | 413 | } |
| 414 | |||
| 415 | driverViewModel.isInteractionAllowed.collect(viewLifecycleOwner) { | ||
| 416 | if (it) startEmulation() | ||
| 417 | } | ||
| 477 | } | 418 | } |
| 478 | 419 | ||
| 479 | private fun startEmulation(programIndex: Int = 0) { | 420 | private fun startEmulation(programIndex: Int = 0) { |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GameFoldersFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GameFoldersFragment.kt index 5c558b1a5..3a6f7a38c 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GameFoldersFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GameFoldersFragment.kt | |||
| @@ -13,9 +13,6 @@ import androidx.core.view.WindowInsetsCompat | |||
| 13 | import androidx.core.view.updatePadding | 13 | import androidx.core.view.updatePadding |
| 14 | import androidx.fragment.app.Fragment | 14 | import androidx.fragment.app.Fragment |
| 15 | import androidx.fragment.app.activityViewModels | 15 | import androidx.fragment.app.activityViewModels |
| 16 | import androidx.lifecycle.Lifecycle | ||
| 17 | import androidx.lifecycle.lifecycleScope | ||
| 18 | import androidx.lifecycle.repeatOnLifecycle | ||
| 19 | import androidx.navigation.findNavController | 16 | import androidx.navigation.findNavController |
| 20 | import androidx.recyclerview.widget.GridLayoutManager | 17 | import androidx.recyclerview.widget.GridLayoutManager |
| 21 | import com.google.android.material.transition.MaterialSharedAxis | 18 | import com.google.android.material.transition.MaterialSharedAxis |
| @@ -27,6 +24,7 @@ import org.yuzu.yuzu_emu.model.GamesViewModel | |||
| 27 | import org.yuzu.yuzu_emu.model.HomeViewModel | 24 | import org.yuzu.yuzu_emu.model.HomeViewModel |
| 28 | import org.yuzu.yuzu_emu.ui.main.MainActivity | 25 | import org.yuzu.yuzu_emu.ui.main.MainActivity |
| 29 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins | 26 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins |
| 27 | import org.yuzu.yuzu_emu.utils.collect | ||
| 30 | 28 | ||
| 31 | class GameFoldersFragment : Fragment() { | 29 | class GameFoldersFragment : Fragment() { |
| 32 | private var _binding: FragmentFoldersBinding? = null | 30 | private var _binding: FragmentFoldersBinding? = null |
| @@ -70,12 +68,8 @@ class GameFoldersFragment : Fragment() { | |||
| 70 | adapter = FolderAdapter(requireActivity(), gamesViewModel) | 68 | adapter = FolderAdapter(requireActivity(), gamesViewModel) |
| 71 | } | 69 | } |
| 72 | 70 | ||
| 73 | viewLifecycleOwner.lifecycleScope.launch { | 71 | gamesViewModel.folders.collect(viewLifecycleOwner) { |
| 74 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 72 | (binding.listFolders.adapter as FolderAdapter).submitList(it) |
| 75 | gamesViewModel.folders.collect { | ||
| 76 | (binding.listFolders.adapter as FolderAdapter).submitList(it) | ||
| 77 | } | ||
| 78 | } | ||
| 79 | } | 73 | } |
| 80 | 74 | ||
| 81 | val mainActivity = requireActivity() as MainActivity | 75 | val mainActivity = requireActivity() as MainActivity |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt index c4da1a65d..c06842c59 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | package org.yuzu.yuzu_emu.fragments | 4 | package org.yuzu.yuzu_emu.fragments |
| 5 | 5 | ||
| 6 | import android.annotation.SuppressLint | ||
| 7 | import android.content.pm.ShortcutInfo | 6 | import android.content.pm.ShortcutInfo |
| 8 | import android.content.pm.ShortcutManager | 7 | import android.content.pm.ShortcutManager |
| 9 | import android.os.Bundle | 8 | import android.os.Bundle |
| @@ -17,9 +16,7 @@ import androidx.core.view.WindowInsetsCompat | |||
| 17 | import androidx.core.view.updatePadding | 16 | 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.lifecycle.Lifecycle | ||
| 21 | import androidx.lifecycle.lifecycleScope | 19 | import androidx.lifecycle.lifecycleScope |
| 22 | import androidx.lifecycle.repeatOnLifecycle | ||
| 23 | import androidx.navigation.findNavController | 20 | import androidx.navigation.findNavController |
| 24 | import androidx.navigation.fragment.navArgs | 21 | import androidx.navigation.fragment.navArgs |
| 25 | import androidx.recyclerview.widget.GridLayoutManager | 22 | import androidx.recyclerview.widget.GridLayoutManager |
| @@ -47,6 +44,7 @@ import org.yuzu.yuzu_emu.utils.GpuDriverHelper | |||
| 47 | import org.yuzu.yuzu_emu.utils.MemoryUtil | 44 | import org.yuzu.yuzu_emu.utils.MemoryUtil |
| 48 | import org.yuzu.yuzu_emu.utils.ViewUtils.marquee | 45 | import org.yuzu.yuzu_emu.utils.ViewUtils.marquee |
| 49 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins | 46 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins |
| 47 | import org.yuzu.yuzu_emu.utils.collect | ||
| 50 | import java.io.BufferedOutputStream | 48 | import java.io.BufferedOutputStream |
| 51 | import java.io.File | 49 | import java.io.File |
| 52 | 50 | ||
| @@ -76,8 +74,6 @@ class GamePropertiesFragment : Fragment() { | |||
| 76 | return binding.root | 74 | return binding.root |
| 77 | } | 75 | } |
| 78 | 76 | ||
| 79 | // This is using the correct scope, lint is just acting up | ||
| 80 | @SuppressLint("UnsafeRepeatOnLifecycleDetector") | ||
| 81 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | 77 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 82 | super.onViewCreated(view, savedInstanceState) | 78 | super.onViewCreated(view, savedInstanceState) |
| 83 | homeViewModel.setNavigationVisibility(visible = false, animated = true) | 79 | homeViewModel.setNavigationVisibility(visible = false, animated = true) |
| @@ -116,28 +112,14 @@ class GamePropertiesFragment : Fragment() { | |||
| 116 | 112 | ||
| 117 | reloadList() | 113 | reloadList() |
| 118 | 114 | ||
| 119 | viewLifecycleOwner.lifecycleScope.apply { | 115 | homeViewModel.openImportSaves.collect( |
| 120 | launch { | 116 | viewLifecycleOwner, |
| 121 | repeatOnLifecycle(Lifecycle.State.STARTED) { | 117 | resetState = { homeViewModel.setOpenImportSaves(false) } |
| 122 | homeViewModel.openImportSaves.collect { | 118 | ) { if (it) importSaves.launch(arrayOf("application/zip")) } |
| 123 | if (it) { | 119 | homeViewModel.reloadPropertiesList.collect( |
| 124 | importSaves.launch(arrayOf("application/zip")) | 120 | viewLifecycleOwner, |
| 125 | homeViewModel.setOpenImportSaves(false) | 121 | resetState = { homeViewModel.reloadPropertiesList(false) } |
| 126 | } | 122 | ) { if (it) reloadList() } |
| 127 | } | ||
| 128 | } | ||
| 129 | } | ||
| 130 | launch { | ||
| 131 | repeatOnLifecycle(Lifecycle.State.STARTED) { | ||
| 132 | homeViewModel.reloadPropertiesList.collect { | ||
| 133 | if (it) { | ||
| 134 | reloadList() | ||
| 135 | homeViewModel.reloadPropertiesList(false) | ||
| 136 | } | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | } | ||
| 141 | 123 | ||
| 142 | setInsets() | 124 | setInsets() |
| 143 | } | 125 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt index 63112dc6f..d218da1c8 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt | |||
| @@ -14,9 +14,6 @@ import androidx.core.view.WindowInsetsCompat | |||
| 14 | import androidx.core.view.updatePadding | 14 | import androidx.core.view.updatePadding |
| 15 | import androidx.fragment.app.Fragment | 15 | import androidx.fragment.app.Fragment |
| 16 | import androidx.fragment.app.activityViewModels | 16 | import androidx.fragment.app.activityViewModels |
| 17 | import androidx.lifecycle.Lifecycle | ||
| 18 | import androidx.lifecycle.lifecycleScope | ||
| 19 | import androidx.lifecycle.repeatOnLifecycle | ||
| 20 | import androidx.navigation.findNavController | 17 | import androidx.navigation.findNavController |
| 21 | import androidx.recyclerview.widget.GridLayoutManager | 18 | import androidx.recyclerview.widget.GridLayoutManager |
| 22 | import com.google.android.material.transition.MaterialSharedAxis | 19 | import com.google.android.material.transition.MaterialSharedAxis |
| @@ -35,6 +32,7 @@ import org.yuzu.yuzu_emu.ui.main.MainActivity | |||
| 35 | import org.yuzu.yuzu_emu.utils.DirectoryInitialization | 32 | import org.yuzu.yuzu_emu.utils.DirectoryInitialization |
| 36 | import org.yuzu.yuzu_emu.utils.FileUtil | 33 | import org.yuzu.yuzu_emu.utils.FileUtil |
| 37 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins | 34 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins |
| 35 | import org.yuzu.yuzu_emu.utils.collect | ||
| 38 | import java.io.BufferedOutputStream | 36 | import java.io.BufferedOutputStream |
| 39 | import java.io.File | 37 | import java.io.File |
| 40 | import java.math.BigInteger | 38 | import java.math.BigInteger |
| @@ -75,14 +73,10 @@ class InstallableFragment : Fragment() { | |||
| 75 | binding.root.findNavController().popBackStack() | 73 | binding.root.findNavController().popBackStack() |
| 76 | } | 74 | } |
| 77 | 75 | ||
| 78 | viewLifecycleOwner.lifecycleScope.launch { | 76 | homeViewModel.openImportSaves.collect(viewLifecycleOwner) { |
| 79 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 77 | if (it) { |
| 80 | homeViewModel.openImportSaves.collect { | 78 | importSaves.launch(arrayOf("application/zip")) |
| 81 | if (it) { | 79 | homeViewModel.setOpenImportSaves(false) |
| 82 | importSaves.launch(arrayOf("application/zip")) | ||
| 83 | homeViewModel.setOpenImportSaves(false) | ||
| 84 | } | ||
| 85 | } | ||
| 86 | } | 80 | } |
| 87 | } | 81 | } |
| 88 | 82 | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ProgressDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ProgressDialogFragment.kt index ae29e9cd1..ee3bb0386 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ProgressDialogFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ProgressDialogFragment.kt | |||
| @@ -13,16 +13,13 @@ import androidx.appcompat.app.AlertDialog | |||
| 13 | import androidx.fragment.app.DialogFragment | 13 | import androidx.fragment.app.DialogFragment |
| 14 | import androidx.fragment.app.FragmentActivity | 14 | import androidx.fragment.app.FragmentActivity |
| 15 | import androidx.fragment.app.activityViewModels | 15 | import androidx.fragment.app.activityViewModels |
| 16 | import androidx.lifecycle.Lifecycle | ||
| 17 | import androidx.lifecycle.ViewModelProvider | 16 | import androidx.lifecycle.ViewModelProvider |
| 18 | import androidx.lifecycle.lifecycleScope | ||
| 19 | import androidx.lifecycle.repeatOnLifecycle | ||
| 20 | import com.google.android.material.dialog.MaterialAlertDialogBuilder | 17 | import com.google.android.material.dialog.MaterialAlertDialogBuilder |
| 21 | import kotlinx.coroutines.launch | ||
| 22 | import org.yuzu.yuzu_emu.R | 18 | import org.yuzu.yuzu_emu.R |
| 23 | import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding | 19 | import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding |
| 24 | import org.yuzu.yuzu_emu.model.TaskViewModel | 20 | import org.yuzu.yuzu_emu.model.TaskViewModel |
| 25 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible | 21 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
| 22 | import org.yuzu.yuzu_emu.utils.collect | ||
| 26 | 23 | ||
| 27 | class ProgressDialogFragment : DialogFragment() { | 24 | class ProgressDialogFragment : DialogFragment() { |
| 28 | private val taskViewModel: TaskViewModel by activityViewModels() | 25 | private val taskViewModel: TaskViewModel by activityViewModels() |
| @@ -65,70 +62,50 @@ class ProgressDialogFragment : DialogFragment() { | |||
| 65 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | 62 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 66 | super.onViewCreated(view, savedInstanceState) | 63 | super.onViewCreated(view, savedInstanceState) |
| 67 | binding.message.isSelected = true | 64 | binding.message.isSelected = true |
| 68 | viewLifecycleOwner.lifecycleScope.apply { | 65 | taskViewModel.isComplete.collect(viewLifecycleOwner) { |
| 69 | launch { | 66 | if (it) { |
| 70 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 67 | dismiss() |
| 71 | taskViewModel.isComplete.collect { | 68 | when (val result = taskViewModel.result.value) { |
| 72 | if (it) { | 69 | is String -> Toast.makeText( |
| 73 | dismiss() | 70 | requireContext(), |
| 74 | when (val result = taskViewModel.result.value) { | 71 | result, |
| 75 | is String -> Toast.makeText( | 72 | Toast.LENGTH_LONG |
| 76 | requireContext(), | 73 | ).show() |
| 77 | result, | 74 | |
| 78 | Toast.LENGTH_LONG | 75 | is MessageDialogFragment -> result.show( |
| 79 | ).show() | 76 | requireActivity().supportFragmentManager, |
| 80 | 77 | MessageDialogFragment.TAG | |
| 81 | is MessageDialogFragment -> result.show( | 78 | ) |
| 82 | requireActivity().supportFragmentManager, | 79 | |
| 83 | MessageDialogFragment.TAG | 80 | else -> { |
| 84 | ) | 81 | // Do nothing |
| 85 | |||
| 86 | else -> { | ||
| 87 | // Do nothing | ||
| 88 | } | ||
| 89 | } | ||
| 90 | taskViewModel.clear() | ||
| 91 | } | ||
| 92 | } | 82 | } |
| 93 | } | 83 | } |
| 84 | taskViewModel.clear() | ||
| 94 | } | 85 | } |
| 95 | launch { | 86 | } |
| 96 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 87 | taskViewModel.cancelled.collect(viewLifecycleOwner) { |
| 97 | taskViewModel.cancelled.collect { | 88 | if (it) { |
| 98 | if (it) { | 89 | dialog?.setTitle(R.string.cancelling) |
| 99 | dialog?.setTitle(R.string.cancelling) | ||
| 100 | } | ||
| 101 | } | ||
| 102 | } | ||
| 103 | } | ||
| 104 | launch { | ||
| 105 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 106 | taskViewModel.progress.collect { | ||
| 107 | if (it != 0.0) { | ||
| 108 | binding.progressBar.apply { | ||
| 109 | isIndeterminate = false | ||
| 110 | progress = ( | ||
| 111 | (it / taskViewModel.maxProgress.value) * | ||
| 112 | PROGRESS_BAR_RESOLUTION | ||
| 113 | ).toInt() | ||
| 114 | min = 0 | ||
| 115 | max = PROGRESS_BAR_RESOLUTION | ||
| 116 | } | ||
| 117 | } | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } | 90 | } |
| 121 | launch { | 91 | } |
| 122 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 92 | taskViewModel.progress.collect(viewLifecycleOwner) { |
| 123 | taskViewModel.message.collect { | 93 | if (it != 0.0) { |
| 124 | binding.message.setVisible(it.isNotEmpty()) | 94 | binding.progressBar.apply { |
| 125 | if (it.isNotEmpty()) { | 95 | isIndeterminate = false |
| 126 | binding.message.text = it | 96 | progress = ( |
| 127 | } | 97 | (it / taskViewModel.maxProgress.value) * |
| 128 | } | 98 | PROGRESS_BAR_RESOLUTION |
| 99 | ).toInt() | ||
| 100 | min = 0 | ||
| 101 | max = PROGRESS_BAR_RESOLUTION | ||
| 129 | } | 102 | } |
| 130 | } | 103 | } |
| 131 | } | 104 | } |
| 105 | taskViewModel.message.collect(viewLifecycleOwner) { | ||
| 106 | binding.message.setVisible(it.isNotEmpty()) | ||
| 107 | binding.message.text = it | ||
| 108 | } | ||
| 132 | } | 109 | } |
| 133 | 110 | ||
| 134 | // By default, the ProgressDialog will immediately dismiss itself upon a button being pressed. | 111 | // By default, the ProgressDialog will immediately dismiss itself upon a button being pressed. |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt index 9f6509605..662ae9760 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | package org.yuzu.yuzu_emu.fragments | 4 | package org.yuzu.yuzu_emu.fragments |
| 5 | 5 | ||
| 6 | import android.annotation.SuppressLint | ||
| 7 | import android.content.Context | 6 | import android.content.Context |
| 8 | import android.content.SharedPreferences | 7 | import android.content.SharedPreferences |
| 9 | import android.os.Bundle | 8 | import android.os.Bundle |
| @@ -18,14 +17,9 @@ import androidx.core.view.updatePadding | |||
| 18 | import androidx.core.widget.doOnTextChanged | 17 | import androidx.core.widget.doOnTextChanged |
| 19 | import androidx.fragment.app.Fragment | 18 | import androidx.fragment.app.Fragment |
| 20 | import androidx.fragment.app.activityViewModels | 19 | import androidx.fragment.app.activityViewModels |
| 21 | import androidx.lifecycle.Lifecycle | ||
| 22 | import androidx.lifecycle.lifecycleScope | ||
| 23 | import androidx.lifecycle.repeatOnLifecycle | ||
| 24 | import androidx.preference.PreferenceManager | 20 | import androidx.preference.PreferenceManager |
| 25 | import info.debatty.java.stringsimilarity.Jaccard | 21 | import info.debatty.java.stringsimilarity.Jaccard |
| 26 | import info.debatty.java.stringsimilarity.JaroWinkler | 22 | import info.debatty.java.stringsimilarity.JaroWinkler |
| 27 | import kotlinx.coroutines.flow.collectLatest | ||
| 28 | import kotlinx.coroutines.launch | ||
| 29 | import java.util.Locale | 23 | import java.util.Locale |
| 30 | import org.yuzu.yuzu_emu.R | 24 | import org.yuzu.yuzu_emu.R |
| 31 | import org.yuzu.yuzu_emu.YuzuApplication | 25 | import org.yuzu.yuzu_emu.YuzuApplication |
| @@ -36,6 +30,7 @@ import org.yuzu.yuzu_emu.model.Game | |||
| 36 | import org.yuzu.yuzu_emu.model.GamesViewModel | 30 | import org.yuzu.yuzu_emu.model.GamesViewModel |
| 37 | import org.yuzu.yuzu_emu.model.HomeViewModel | 31 | import org.yuzu.yuzu_emu.model.HomeViewModel |
| 38 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible | 32 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
| 33 | import org.yuzu.yuzu_emu.utils.collect | ||
| 39 | 34 | ||
| 40 | class SearchFragment : Fragment() { | 35 | class SearchFragment : Fragment() { |
| 41 | private var _binding: FragmentSearchBinding? = null | 36 | private var _binding: FragmentSearchBinding? = null |
| @@ -59,8 +54,6 @@ class SearchFragment : Fragment() { | |||
| 59 | return binding.root | 54 | return binding.root |
| 60 | } | 55 | } |
| 61 | 56 | ||
| 62 | // This is using the correct scope, lint is just acting up | ||
| 63 | @SuppressLint("UnsafeRepeatOnLifecycleDetector") | ||
| 64 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | 57 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 65 | super.onViewCreated(view, savedInstanceState) | 58 | super.onViewCreated(view, savedInstanceState) |
| 66 | homeViewModel.setNavigationVisibility(visible = true, animated = true) | 59 | homeViewModel.setNavigationVisibility(visible = true, animated = true) |
| @@ -86,30 +79,14 @@ class SearchFragment : Fragment() { | |||
| 86 | filterAndSearch() | 79 | filterAndSearch() |
| 87 | } | 80 | } |
| 88 | 81 | ||
| 89 | viewLifecycleOwner.lifecycleScope.apply { | 82 | gamesViewModel.searchFocused.collect( |
| 90 | launch { | 83 | viewLifecycleOwner, |
| 91 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 84 | resetState = { gamesViewModel.setSearchFocused(false) } |
| 92 | gamesViewModel.searchFocused.collect { | 85 | ) { if (it) focusSearch() } |
| 93 | if (it) { | 86 | gamesViewModel.games.collect(viewLifecycleOwner) { filterAndSearch() } |
| 94 | focusSearch() | 87 | gamesViewModel.searchedGames.collect(viewLifecycleOwner) { |
| 95 | gamesViewModel.setSearchFocused(false) | 88 | (binding.gridGamesSearch.adapter as GameAdapter).submitList(it) |
| 96 | } | 89 | binding.noResultsView.setVisible(it.isNotEmpty()) |
| 97 | } | ||
| 98 | } | ||
| 99 | } | ||
| 100 | launch { | ||
| 101 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 102 | gamesViewModel.games.collectLatest { filterAndSearch() } | ||
| 103 | } | ||
| 104 | } | ||
| 105 | launch { | ||
| 106 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 107 | gamesViewModel.searchedGames.collect { | ||
| 108 | (binding.gridGamesSearch.adapter as GameAdapter).submitList(it) | ||
| 109 | binding.noResultsView.setVisible(it.isEmpty()) | ||
| 110 | } | ||
| 111 | } | ||
| 112 | } | ||
| 113 | } | 90 | } |
| 114 | 91 | ||
| 115 | binding.clearButton.setOnClickListener { binding.searchText.setText("") } | 92 | binding.clearButton.setOnClickListener { binding.searchText.setText("") } |
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 eb279d309..4f7548e98 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 | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | package org.yuzu.yuzu_emu.fragments | 4 | package org.yuzu.yuzu_emu.fragments |
| 5 | 5 | ||
| 6 | import android.Manifest | 6 | import android.Manifest |
| 7 | import android.annotation.SuppressLint | ||
| 8 | import android.content.Intent | 7 | import android.content.Intent |
| 9 | import android.os.Build | 8 | import android.os.Build |
| 10 | import android.os.Bundle | 9 | import android.os.Bundle |
| @@ -23,9 +22,6 @@ import androidx.core.view.isVisible | |||
| 23 | import androidx.core.view.updatePadding | 22 | import androidx.core.view.updatePadding |
| 24 | import androidx.fragment.app.Fragment | 23 | import androidx.fragment.app.Fragment |
| 25 | import androidx.fragment.app.activityViewModels | 24 | import androidx.fragment.app.activityViewModels |
| 26 | import androidx.lifecycle.Lifecycle | ||
| 27 | import androidx.lifecycle.lifecycleScope | ||
| 28 | import androidx.lifecycle.repeatOnLifecycle | ||
| 29 | import androidx.navigation.findNavController | 25 | import androidx.navigation.findNavController |
| 30 | import androidx.preference.PreferenceManager | 26 | import androidx.preference.PreferenceManager |
| 31 | import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback | 27 | import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback |
| @@ -47,6 +43,7 @@ import org.yuzu.yuzu_emu.utils.DirectoryInitialization | |||
| 47 | import org.yuzu.yuzu_emu.utils.NativeConfig | 43 | import org.yuzu.yuzu_emu.utils.NativeConfig |
| 48 | import org.yuzu.yuzu_emu.utils.ViewUtils | 44 | import org.yuzu.yuzu_emu.utils.ViewUtils |
| 49 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible | 45 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
| 46 | import org.yuzu.yuzu_emu.utils.collect | ||
| 50 | 47 | ||
| 51 | class SetupFragment : Fragment() { | 48 | class SetupFragment : Fragment() { |
| 52 | private var _binding: FragmentSetupBinding? = null | 49 | private var _binding: FragmentSetupBinding? = null |
| @@ -78,8 +75,6 @@ class SetupFragment : Fragment() { | |||
| 78 | return binding.root | 75 | return binding.root |
| 79 | } | 76 | } |
| 80 | 77 | ||
| 81 | // This is using the correct scope, lint is just acting up | ||
| 82 | @SuppressLint("UnsafeRepeatOnLifecycleDetector") | ||
| 83 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | 78 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 84 | mainActivity = requireActivity() as MainActivity | 79 | mainActivity = requireActivity() as MainActivity |
| 85 | 80 | ||
| @@ -211,28 +206,14 @@ class SetupFragment : Fragment() { | |||
| 211 | ) | 206 | ) |
| 212 | } | 207 | } |
| 213 | 208 | ||
| 214 | viewLifecycleOwner.lifecycleScope.apply { | 209 | homeViewModel.shouldPageForward.collect( |
| 215 | launch { | 210 | viewLifecycleOwner, |
| 216 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 211 | resetState = { homeViewModel.setShouldPageForward(false) } |
| 217 | homeViewModel.shouldPageForward.collect { | 212 | ) { if (it) pageForward() } |
| 218 | if (it) { | 213 | homeViewModel.gamesDirSelected.collect( |
| 219 | pageForward() | 214 | viewLifecycleOwner, |
| 220 | homeViewModel.setShouldPageForward(false) | 215 | resetState = { homeViewModel.setGamesDirSelected(false) } |
| 221 | } | 216 | ) { if (it) gamesDirCallback.onStepCompleted() } |
| 222 | } | ||
| 223 | } | ||
| 224 | } | ||
| 225 | launch { | ||
| 226 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 227 | homeViewModel.gamesDirSelected.collect { | ||
| 228 | if (it) { | ||
| 229 | gamesDirCallback.onStepCompleted() | ||
| 230 | homeViewModel.setGamesDirSelected(false) | ||
| 231 | } | ||
| 232 | } | ||
| 233 | } | ||
| 234 | } | ||
| 235 | } | ||
| 236 | 217 | ||
| 237 | binding.viewPager2.apply { | 218 | binding.viewPager2.apply { |
| 238 | adapter = SetupAdapter(requireActivity() as AppCompatActivity, pages) | 219 | adapter = SetupAdapter(requireActivity() as AppCompatActivity, pages) |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt index b3248585e..fadb20e39 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | package org.yuzu.yuzu_emu.ui | 4 | package org.yuzu.yuzu_emu.ui |
| 5 | 5 | ||
| 6 | import android.annotation.SuppressLint | ||
| 7 | import android.os.Bundle | 6 | import android.os.Bundle |
| 8 | import android.view.LayoutInflater | 7 | import android.view.LayoutInflater |
| 9 | import android.view.View | 8 | import android.view.View |
| @@ -14,12 +13,7 @@ import androidx.core.view.WindowInsetsCompat | |||
| 14 | import androidx.core.view.updatePadding | 13 | import androidx.core.view.updatePadding |
| 15 | import androidx.fragment.app.Fragment | 14 | import androidx.fragment.app.Fragment |
| 16 | import androidx.fragment.app.activityViewModels | 15 | import androidx.fragment.app.activityViewModels |
| 17 | import androidx.lifecycle.Lifecycle | ||
| 18 | import androidx.lifecycle.lifecycleScope | ||
| 19 | import androidx.lifecycle.repeatOnLifecycle | ||
| 20 | import com.google.android.material.color.MaterialColors | 16 | import com.google.android.material.color.MaterialColors |
| 21 | import kotlinx.coroutines.flow.collectLatest | ||
| 22 | import kotlinx.coroutines.launch | ||
| 23 | import org.yuzu.yuzu_emu.R | 17 | import org.yuzu.yuzu_emu.R |
| 24 | import org.yuzu.yuzu_emu.adapters.GameAdapter | 18 | import org.yuzu.yuzu_emu.adapters.GameAdapter |
| 25 | import org.yuzu.yuzu_emu.databinding.FragmentGamesBinding | 19 | import org.yuzu.yuzu_emu.databinding.FragmentGamesBinding |
| @@ -28,6 +22,7 @@ import org.yuzu.yuzu_emu.model.GamesViewModel | |||
| 28 | import org.yuzu.yuzu_emu.model.HomeViewModel | 22 | import org.yuzu.yuzu_emu.model.HomeViewModel |
| 29 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible | 23 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
| 30 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins | 24 | import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins |
| 25 | import org.yuzu.yuzu_emu.utils.collect | ||
| 31 | 26 | ||
| 32 | class GamesFragment : Fragment() { | 27 | class GamesFragment : Fragment() { |
| 33 | private var _binding: FragmentGamesBinding? = null | 28 | private var _binding: FragmentGamesBinding? = null |
| @@ -45,8 +40,6 @@ class GamesFragment : Fragment() { | |||
| 45 | return binding.root | 40 | return binding.root |
| 46 | } | 41 | } |
| 47 | 42 | ||
| 48 | // This is using the correct scope, lint is just acting up | ||
| 49 | @SuppressLint("UnsafeRepeatOnLifecycleDetector") | ||
| 50 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | 43 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 51 | super.onViewCreated(view, savedInstanceState) | 44 | super.onViewCreated(view, savedInstanceState) |
| 52 | homeViewModel.setNavigationVisibility(visible = true, animated = true) | 45 | homeViewModel.setNavigationVisibility(visible = true, animated = true) |
| @@ -89,48 +82,28 @@ class GamesFragment : Fragment() { | |||
| 89 | } | 82 | } |
| 90 | } | 83 | } |
| 91 | 84 | ||
| 92 | viewLifecycleOwner.lifecycleScope.apply { | 85 | gamesViewModel.isReloading.collect(viewLifecycleOwner) { |
| 93 | launch { | 86 | binding.swipeRefresh.isRefreshing = it |
| 94 | repeatOnLifecycle(Lifecycle.State.RESUMED) { | 87 | binding.noticeText.setVisible( |
| 95 | gamesViewModel.isReloading.collect { | 88 | visible = gamesViewModel.games.value.isEmpty() && !it, |
| 96 | binding.swipeRefresh.isRefreshing = it | 89 | gone = false |
| 97 | binding.noticeText.setVisible( | 90 | ) |
| 98 | visible = gamesViewModel.games.value.isEmpty() && !it, | 91 | } |
| 99 | gone = false | 92 | gamesViewModel.games.collect(viewLifecycleOwner) { |
| 100 | ) | 93 | (binding.gridGames.adapter as GameAdapter).submitList(it) |
| 101 | } | 94 | } |
| 102 | } | 95 | gamesViewModel.shouldSwapData.collect( |
| 103 | } | 96 | viewLifecycleOwner, |
| 104 | launch { | 97 | resetState = { gamesViewModel.setShouldSwapData(false) } |
| 105 | repeatOnLifecycle(Lifecycle.State.RESUMED) { | 98 | ) { |
| 106 | gamesViewModel.games.collectLatest { | 99 | if (it) { |
| 107 | (binding.gridGames.adapter as GameAdapter).submitList(it) | 100 | (binding.gridGames.adapter as GameAdapter).submitList(gamesViewModel.games.value) |
| 108 | } | ||
| 109 | } | ||
| 110 | } | ||
| 111 | launch { | ||
| 112 | repeatOnLifecycle(Lifecycle.State.RESUMED) { | ||
| 113 | gamesViewModel.shouldSwapData.collect { | ||
| 114 | if (it) { | ||
| 115 | (binding.gridGames.adapter as GameAdapter).submitList( | ||
| 116 | gamesViewModel.games.value | ||
| 117 | ) | ||
| 118 | gamesViewModel.setShouldSwapData(false) | ||
| 119 | } | ||
| 120 | } | ||
| 121 | } | ||
| 122 | } | ||
| 123 | launch { | ||
| 124 | repeatOnLifecycle(Lifecycle.State.RESUMED) { | ||
| 125 | gamesViewModel.shouldScrollToTop.collect { | ||
| 126 | if (it) { | ||
| 127 | scrollToTop() | ||
| 128 | gamesViewModel.setShouldScrollToTop(false) | ||
| 129 | } | ||
| 130 | } | ||
| 131 | } | ||
| 132 | } | 101 | } |
| 133 | } | 102 | } |
| 103 | gamesViewModel.shouldScrollToTop.collect( | ||
| 104 | viewLifecycleOwner, | ||
| 105 | resetState = { gamesViewModel.setShouldScrollToTop(false) } | ||
| 106 | ) { if (it) scrollToTop() } | ||
| 134 | 107 | ||
| 135 | setInsets() | 108 | setInsets() |
| 136 | } | 109 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt index 703fbaf3e..d16f8a931 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt | |||
| @@ -19,9 +19,6 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen | |||
| 19 | import androidx.core.view.ViewCompat | 19 | import androidx.core.view.ViewCompat |
| 20 | import androidx.core.view.WindowCompat | 20 | import androidx.core.view.WindowCompat |
| 21 | import androidx.core.view.WindowInsetsCompat | 21 | import androidx.core.view.WindowInsetsCompat |
| 22 | import androidx.lifecycle.Lifecycle | ||
| 23 | import androidx.lifecycle.lifecycleScope | ||
| 24 | import androidx.lifecycle.repeatOnLifecycle | ||
| 25 | import androidx.navigation.NavController | 22 | import androidx.navigation.NavController |
| 26 | import androidx.navigation.fragment.NavHostFragment | 23 | import androidx.navigation.fragment.NavHostFragment |
| 27 | import androidx.navigation.ui.setupWithNavController | 24 | import androidx.navigation.ui.setupWithNavController |
| @@ -30,7 +27,6 @@ import com.google.android.material.color.MaterialColors | |||
| 30 | import com.google.android.material.navigation.NavigationBarView | 27 | import com.google.android.material.navigation.NavigationBarView |
| 31 | import java.io.File | 28 | import java.io.File |
| 32 | import java.io.FilenameFilter | 29 | import java.io.FilenameFilter |
| 33 | import kotlinx.coroutines.launch | ||
| 34 | import org.yuzu.yuzu_emu.HomeNavigationDirections | 30 | import org.yuzu.yuzu_emu.HomeNavigationDirections |
| 35 | import org.yuzu.yuzu_emu.NativeLibrary | 31 | import org.yuzu.yuzu_emu.NativeLibrary |
| 36 | import org.yuzu.yuzu_emu.R | 32 | import org.yuzu.yuzu_emu.R |
| @@ -144,38 +140,19 @@ class MainActivity : AppCompatActivity(), ThemeProvider { | |||
| 144 | binding.statusBarShade.setVisible(visible = false, gone = false) | 140 | binding.statusBarShade.setVisible(visible = false, gone = false) |
| 145 | } | 141 | } |
| 146 | 142 | ||
| 147 | lifecycleScope.apply { | 143 | homeViewModel.navigationVisible.collect(this) { showNavigation(it.first, it.second) } |
| 148 | launch { | 144 | homeViewModel.statusBarShadeVisible.collect(this) { showStatusBarShade(it) } |
| 149 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 145 | homeViewModel.contentToInstall.collect( |
| 150 | homeViewModel.navigationVisible.collect { showNavigation(it.first, it.second) } | 146 | this, |
| 151 | } | 147 | resetState = { homeViewModel.setContentToInstall(null) } |
| 152 | } | 148 | ) { |
| 153 | launch { | 149 | if (it != null) { |
| 154 | repeatOnLifecycle(Lifecycle.State.CREATED) { | 150 | installContent(it) |
| 155 | homeViewModel.statusBarShadeVisible.collect { showStatusBarShade(it) } | ||
| 156 | } | ||
| 157 | } | ||
| 158 | launch { | ||
| 159 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 160 | homeViewModel.contentToInstall.collect { | ||
| 161 | if (it != null) { | ||
| 162 | installContent(it) | ||
| 163 | homeViewModel.setContentToInstall(null) | ||
| 164 | } | ||
| 165 | } | ||
| 166 | } | ||
| 167 | } | ||
| 168 | launch { | ||
| 169 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 170 | homeViewModel.checkKeys.collect { | ||
| 171 | if (it) { | ||
| 172 | checkKeys() | ||
| 173 | homeViewModel.setCheckKeys(false) | ||
| 174 | } | ||
| 175 | } | ||
| 176 | } | ||
| 177 | } | 151 | } |
| 178 | } | 152 | } |
| 153 | homeViewModel.checkKeys.collect(this, resetState = { homeViewModel.setCheckKeys(false) }) { | ||
| 154 | if (it) checkKeys() | ||
| 155 | } | ||
| 179 | 156 | ||
| 180 | setInsets() | 157 | setInsets() |
| 181 | } | 158 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/LifecycleUtils.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/LifecycleUtils.kt new file mode 100644 index 000000000..d5c19c681 --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/LifecycleUtils.kt | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | package org.yuzu.yuzu_emu.utils | ||
| 5 | |||
| 6 | import androidx.lifecycle.Lifecycle | ||
| 7 | import androidx.lifecycle.LifecycleOwner | ||
| 8 | import androidx.lifecycle.lifecycleScope | ||
| 9 | import androidx.lifecycle.repeatOnLifecycle | ||
| 10 | import kotlinx.coroutines.flow.Flow | ||
| 11 | import kotlinx.coroutines.flow.MutableStateFlow | ||
| 12 | import kotlinx.coroutines.launch | ||
| 13 | |||
| 14 | /** | ||
| 15 | * Collects this [Flow] with a given [LifecycleOwner]. | ||
| 16 | * @param scope [LifecycleOwner] that this [Flow] will be collected with. | ||
| 17 | * @param repeatState When to repeat collection on this [Flow]. | ||
| 18 | * @param resetState Optional lambda to reset state of an underlying [MutableStateFlow] after | ||
| 19 | * [stateCollector] has been run. | ||
| 20 | * @param stateCollector Lambda that receives new state. | ||
| 21 | */ | ||
| 22 | inline fun <reified T> Flow<T>.collect( | ||
| 23 | scope: LifecycleOwner, | ||
| 24 | repeatState: Lifecycle.State = Lifecycle.State.CREATED, | ||
| 25 | crossinline resetState: () -> Unit = {}, | ||
| 26 | crossinline stateCollector: (state: T) -> Unit | ||
| 27 | ) { | ||
| 28 | scope.apply { | ||
| 29 | lifecycleScope.launch { | ||
| 30 | repeatOnLifecycle(repeatState) { | ||
| 31 | this@collect.collect { | ||
| 32 | stateCollector(it) | ||
| 33 | resetState() | ||
| 34 | } | ||
| 35 | } | ||
| 36 | } | ||
| 37 | } | ||
| 38 | } | ||