[GameProperties] Add share per game config file action
All checks were successful
eden-license / license-header (pull_request) Successful in 37s

This commit is contained in:
nyx 2025-09-13 09:43:20 +02:00
parent 2eed537da1
commit 575bae6dd7

View file

@ -3,9 +3,11 @@
package org.yuzu.yuzu_emu.fragments package org.yuzu.yuzu_emu.fragments
import android.content.Intent
import android.content.pm.ShortcutInfo import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager import android.content.pm.ShortcutManager
import android.os.Bundle import android.os.Bundle
import android.provider.DocumentsContract
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -14,6 +16,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.documentfile.provider.DocumentFile
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -29,12 +32,14 @@ import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication import org.yuzu.yuzu_emu.YuzuApplication
import org.yuzu.yuzu_emu.adapters.GamePropertiesAdapter import org.yuzu.yuzu_emu.adapters.GamePropertiesAdapter
import org.yuzu.yuzu_emu.databinding.FragmentGamePropertiesBinding import org.yuzu.yuzu_emu.databinding.FragmentGamePropertiesBinding
import org.yuzu.yuzu_emu.features.DocumentProvider
import org.yuzu.yuzu_emu.features.settings.model.Settings import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.model.DriverViewModel import org.yuzu.yuzu_emu.model.DriverViewModel
import org.yuzu.yuzu_emu.model.GameProperty import org.yuzu.yuzu_emu.model.GameProperty
import org.yuzu.yuzu_emu.model.GamesViewModel import org.yuzu.yuzu_emu.model.GamesViewModel
import org.yuzu.yuzu_emu.model.HomeViewModel import org.yuzu.yuzu_emu.model.HomeViewModel
import org.yuzu.yuzu_emu.model.InstallableProperty import org.yuzu.yuzu_emu.model.InstallableProperty
import org.yuzu.yuzu_emu.model.SubMenuProperSecondaryAction
import org.yuzu.yuzu_emu.model.SubmenuProperty import org.yuzu.yuzu_emu.model.SubmenuProperty
import org.yuzu.yuzu_emu.model.TaskState import org.yuzu.yuzu_emu.model.TaskState
import org.yuzu.yuzu_emu.utils.DirectoryInitialization import org.yuzu.yuzu_emu.utils.DirectoryInitialization
@ -137,25 +142,44 @@ class GamePropertiesFragment : Fragment() {
SubmenuProperty( SubmenuProperty(
R.string.info, R.string.info,
R.string.info_description, R.string.info_description,
R.drawable.ic_info_outline R.drawable.ic_info_outline,
) { action = {
val action = GamePropertiesFragmentDirections val action = GamePropertiesFragmentDirections
.actionPerGamePropertiesFragmentToGameInfoFragment(args.game) .actionPerGamePropertiesFragmentToGameInfoFragment(args.game)
binding.root.findNavController().navigate(action) binding.root.findNavController().navigate(action)
} }
)
) )
add( add(
SubmenuProperty( SubmenuProperty(
R.string.preferences_settings, R.string.preferences_settings,
R.string.per_game_settings_description, R.string.per_game_settings_description,
R.drawable.ic_settings R.drawable.ic_settings,
) { action = {
val action = HomeNavigationDirections.actionGlobalSettingsActivity( val action = HomeNavigationDirections.actionGlobalSettingsActivity(
args.game, args.game,
Settings.MenuTag.SECTION_ROOT Settings.MenuTag.SECTION_ROOT
)
binding.root.findNavController().navigate(action)
},
secondaryAction = SubMenuProperSecondaryAction(
isShown = File(
DirectoryInitialization.userDirectory +
"/config/custom/" + args.game.settingsName + ".ini"
).exists(),
descriptionId = R.string.share_game_settings,
iconId = R.drawable.ic_share,
action = {
val configFile = File(
DirectoryInitialization.userDirectory +
"/config/custom/" + args.game.settingsName + ".ini"
)
if (configFile.exists()) {
shareConfigFile(configFile)
}
}
) )
binding.root.findNavController().navigate(action) )
}
) )
if (GpuDriverHelper.supportsCustomDriverLoading()) { if (GpuDriverHelper.supportsCustomDriverLoading()) {
@ -164,12 +188,13 @@ class GamePropertiesFragment : Fragment() {
R.string.gpu_driver_manager, R.string.gpu_driver_manager,
R.string.install_gpu_driver_description, R.string.install_gpu_driver_description,
R.drawable.ic_build, R.drawable.ic_build,
detailsFlow = driverViewModel.selectedDriverTitle detailsFlow = driverViewModel.selectedDriverTitle,
) { action = {
val action = GamePropertiesFragmentDirections val action = GamePropertiesFragmentDirections
.actionPerGamePropertiesFragmentToDriverManagerFragment(args.game) .actionPerGamePropertiesFragmentToDriverManagerFragment(args.game)
binding.root.findNavController().navigate(action) binding.root.findNavController().navigate(action)
} }
)
) )
} }
@ -178,12 +203,13 @@ class GamePropertiesFragment : Fragment() {
SubmenuProperty( SubmenuProperty(
R.string.add_ons, R.string.add_ons,
R.string.add_ons_description, R.string.add_ons_description,
R.drawable.ic_edit R.drawable.ic_edit,
) { action = {
val action = GamePropertiesFragmentDirections val action = GamePropertiesFragmentDirections
.actionPerGamePropertiesFragmentToAddonsFragment(args.game) .actionPerGamePropertiesFragmentToAddonsFragment(args.game)
binding.root.findNavController().navigate(action) binding.root.findNavController().navigate(action)
} }
)
) )
add( add(
InstallableProperty( InstallableProperty(
@ -245,7 +271,7 @@ class GamePropertiesFragment : Fragment() {
R.string.clear_shader_cache, R.string.clear_shader_cache,
R.string.clear_shader_cache_description, R.string.clear_shader_cache_description,
R.drawable.ic_delete, R.drawable.ic_delete,
{ details = {
if (shaderCacheDir.exists()) { if (shaderCacheDir.exists()) {
val bytes = shaderCacheDir.walkTopDown().filter { it.isFile } val bytes = shaderCacheDir.walkTopDown().filter { it.isFile }
.map { it.length() }.sum() .map { it.length() }.sum()
@ -253,23 +279,24 @@ class GamePropertiesFragment : Fragment() {
} else { } else {
MemoryUtil.bytesToSizeUnit(0f) MemoryUtil.bytesToSizeUnit(0f)
} }
},
action = {
MessageDialogFragment.newInstance(
requireActivity(),
titleId = R.string.clear_shader_cache,
descriptionId = R.string.clear_shader_cache_warning_description,
positiveAction = {
shaderCacheDir.deleteRecursively()
Toast.makeText(
YuzuApplication.appContext,
R.string.cleared_shaders_successfully,
Toast.LENGTH_SHORT
).show()
homeViewModel.reloadPropertiesList(true)
}
).show(parentFragmentManager, MessageDialogFragment.TAG)
} }
) { )
MessageDialogFragment.newInstance(
requireActivity(),
titleId = R.string.clear_shader_cache,
descriptionId = R.string.clear_shader_cache_warning_description,
positiveAction = {
shaderCacheDir.deleteRecursively()
Toast.makeText(
YuzuApplication.appContext,
R.string.cleared_shaders_successfully,
Toast.LENGTH_SHORT
).show()
homeViewModel.reloadPropertiesList(true)
}
).show(parentFragmentManager, MessageDialogFragment.TAG)
}
) )
} }
} }
@ -284,6 +311,7 @@ class GamePropertiesFragment : Fragment() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
driverViewModel.updateDriverNameForGame(args.game) driverViewModel.updateDriverNameForGame(args.game)
reloadList()
} }
private fun setInsets() = private fun setInsets() =
@ -420,4 +448,30 @@ class GamePropertiesFragment : Fragment() {
} }
}.show(parentFragmentManager, ProgressDialogFragment.TAG) }.show(parentFragmentManager, ProgressDialogFragment.TAG)
} }
private fun shareConfigFile(configFile: File) {
val file = DocumentFile.fromSingleUri(
requireContext(),
DocumentsContract.buildDocumentUri(
DocumentProvider.AUTHORITY,
"${DocumentProvider.ROOT_ID}/${configFile}"
)
)!!
val intent = Intent(Intent.ACTION_SEND)
.setDataAndType(file.uri, FileUtil.TEXT_PLAIN)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
if (file.exists()) {
intent.putExtra(Intent.EXTRA_STREAM, file.uri)
startActivity(Intent.createChooser(intent, getText(R.string.share_game_settings)))
} else {
Toast.makeText(
requireContext(),
getText(R.string.share_config_failed),
Toast.LENGTH_SHORT
).show()
}
}
} }