Add the basic framework to assign game folder

This commit is contained in:
Abandoned Cart 2023-04-21 11:50:36 -04:00
parent 35fb874a42
commit 3921099c53
7 changed files with 175 additions and 3 deletions

View File

@ -25,6 +25,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.snackbar.Snackbar
import emu.skyline.data.AppItem
import emu.skyline.data.AppItemTag
import emu.skyline.data.GameFolders
import emu.skyline.databinding.AppDialogBinding
import emu.skyline.loader.LoaderResult
import emu.skyline.provider.DocumentsProvider
@ -71,6 +72,14 @@ class AppDialog : BottomSheetDialogFragment() {
private val documentPicker = registerForActivityResult(ActivityResultContracts.OpenDocument()) {
it?.let { uri -> importSave(uri) }
}
private val directoryPicker = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) {
it?.let { uri ->
activity?.contentResolver?.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
activity?.contentResolver?.takePersistableUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
GameFolders.putDirectory(item.titleId ?: item.key(), uri.toString())
}
binding.gameFolderPath.text = GameFolders.getDirectoryPath(it)
}
/**
* This inflates the layout of the dialog after initial view creation
@ -151,6 +160,18 @@ class AppDialog : BottomSheetDialogFragment() {
exportSave(saveFolderPath)
}
binding.gameFolderPath.text = GameFolders.getDirectoryPath(item.titleId ?: item.key())
binding.setFolder.setOnClickListener {
directoryPicker.launch(null)
}
binding.clearFolder.setOnClickListener {
GameFolders.removeDirectory(item.titleId ?: item.key())
(activity as? MainActivity)?.loadRoms(false)
binding.gameFolderPath.text = ""
}
binding.gameTitleId.setOnLongClickListener {
val clipboard = requireActivity().getSystemService(android.content.Context.CLIPBOARD_SERVICE) as android.content.ClipboardManager
clipboard.setPrimaryClip(android.content.ClipData.newPlainText("Title ID", item.titleId))

View File

@ -29,6 +29,7 @@ import dagger.hilt.android.AndroidEntryPoint
import emu.skyline.adapter.*
import emu.skyline.data.AppItem
import emu.skyline.data.AppItemTag
import emu.skyline.data.GameFolders
import emu.skyline.databinding.MainActivityBinding
import emu.skyline.loader.AppEntry
import emu.skyline.loader.LoaderResult
@ -215,7 +216,10 @@ class MainActivity : AppCompatActivity() {
private fun sortGameList(gameList : List<AppEntry>) : List<AppEntry> {
val sortedApps : MutableList<AppEntry> = mutableListOf()
gameList.forEach { entry -> sortedApps.add(entry) }
gameList.forEach { entry ->
if (!appSettings.filterGameFolders || !GameFolders.hasDirectory(entry.uri))
sortedApps.add(entry)
}
when (appSettings.sortAppsBy) {
SortingOrder.AlphabeticalAsc.ordinal -> sortedApps.sortBy { it.name }
SortingOrder.AlphabeticalDesc.ordinal -> sortedApps.sortByDescending { it.name }
@ -258,7 +262,7 @@ class MainActivity : AppCompatActivity() {
AppDialog.newInstance(appItem).show(supportFragmentManager, "game")
}
private fun loadRoms(loadFromFile : Boolean) {
fun loadRoms(loadFromFile : Boolean) {
if (!loadFromFile) {
binding.romPlaceholder.isVisible = true
binding.romPlaceholder.text = getString(R.string.searching_roms)

View File

@ -0,0 +1,78 @@
/*
* SPDX-License-Identifier: MPL-2.0
* Copyright © 2023 Skyline Team and Contributors (https://github.com/skyline-emu/)
*/
package emu.skyline.data
import android.content.Context
import android.content.SharedPreferences
import android.net.Uri
import androidx.preference.PreferenceManager
import emu.skyline.SkylineApplication
import org.json.JSONException
import org.json.JSONObject
import java.io.File
object GameFolders {
private val sharedPref : SharedPreferences = PreferenceManager.getDefaultSharedPreferences(SkylineApplication.instance)
private val directories : HashMap<String, String> = hashMapOf()
init {
try {
val jsonString = sharedPref.getString("game_folders", JSONObject().toString())
if (jsonString != null) {
val jsonObject = JSONObject(jsonString)
val keysItr = jsonObject.keys()
while (keysItr.hasNext()) {
val key = keysItr.next()
val value = jsonObject.getString(key)
directories[key] = value
}
}
} catch (e : JSONException) {
e.printStackTrace()
}
}
private fun saveMap(inputMap : Map<String?, String?>) {
val jsonObject = JSONObject(inputMap)
val jsonString = jsonObject.toString()
with (sharedPref.edit()) {
remove("game_folders")
putString("game_folders", jsonString)
apply()
}
}
fun removeDirectory(key: String) {
directories.remove(key)
saveMap(directories.toMap())
}
fun putDirectory(key: String, directory: String) {
directories[key] = directory
saveMap(directories.toMap())
}
private fun getDirectory(key: String) : String? {
return directories[key]
}
fun getDirectoryPath(key: String) : String {
val uri = getDirectory(key)
return uri?.let { Uri.parse(it).path.toString() } ?: ""
}
fun getDirectoryPath(uri: Uri?) : String {
return uri?.path ?: ""
}
fun hasDirectory(uri: Uri) : Boolean {
return directories.values.any { dlcPath ->
uri.path?.substringAfterLast(":")?.startsWith("${Uri.parse(dlcPath).path?.substringAfterLast(":")}${File.separator}") ?: false
}
}
}

View File

@ -24,6 +24,7 @@ class AppSettings @Inject constructor(@ApplicationContext private val context :
var useMaterialYou by sharedPreferences(context, false)
var layoutType by sharedPreferences(context, 1)
var sortAppsBy by sharedPreferences(context, 0)
var filterGameFolders by sharedPreferences(context, false)
var selectAction by sharedPreferences(context, false)
// Input

View File

@ -148,7 +148,6 @@
android:layout_marginTop="8dp"
app:alignItems="center"
app:flexWrap="nowrap"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/save_management"
@ -185,5 +184,62 @@
app:iconGravity="textStart" />
</com.google.android.flexbox.FlexboxLayout>
<TextView
android:id="@+id/game_folder"
style="?attr/textAppearanceLabelLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/game_folder"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/flexboxSaves" />
<TextView
android:id="@+id/game_folder_path"
style="?attr/textAppearanceLabelSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/game_folder" />
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flexboxGameFolder"
style="@style/ThemeOverlay.Material3.Button.IconButton.Filled.Tonal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:alignItems="center"
app:flexWrap="nowrap"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/game_folder_path"
app:layout_constraintVertical_bias="1">
<com.google.android.material.button.MaterialButton
android:id="@+id/set_folder"
style="@style/Widget.Material3.Button.TonalButton.Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/set_game_folder"
android:text="@string/set_game_folder"
app:icon="@drawable/ic_add" />
<com.google.android.material.button.MaterialButton
android:id="@+id/clear_folder"
style="@style/Widget.Material3.Button.TonalButton.Icon"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:contentDescription="@string/clear_game_folder"
android:tooltipText="@string/clear_game_folder"
app:icon="@drawable/ic_delete" />
</com.google.android.flexbox.FlexboxLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

View File

@ -24,6 +24,9 @@
<string name="delete_save">Delete save</string>
<string name="import_save">Import</string>
<string name="export_save">Export</string>
<string name="game_folder">DLC / Update Folder</string>
<string name="set_game_folder">Set Folder</string>
<string name="clear_game_folder">Clear Folder</string>
<string name="searching_roms">Searching for ROMs</string>
<string name="invalid_file">Invalid file</string>
<string name="missing_title_key">Missing title key</string>
@ -56,6 +59,9 @@
<string name="app_language_default">Use System Default</string>
<string name="layout_type">Game Display Layout</string>
<string name="sort_apps_by">Games Sorting Order</string>
<string name="filter_game_folders">Hide DLC / Update Folders</string>
<string name="filter_game_folders_desc_off">Show files in folders assigned to individual games</string>
<string name="filter_game_folders_desc_on">Hide files in folders assigned to individual games</string>
<string name="select_action">Always Show Game Information</string>
<string name="select_action_desc_on">Game information will be shown on clicking a game</string>
<string name="select_action_desc_off">Game information will only be shown on long-clicking a game</string>

View File

@ -51,6 +51,12 @@
app:refreshRequired="true"
app:title="@string/sort_apps_by"
app:useSimpleSummaryProvider="true" />
<emu.skyline.preference.RefreshSwitchPreferenceCompat
android:defaultValue="false"
android:summaryOff="@string/filter_game_folders_desc_off"
android:summaryOn="@string/filter_game_folders_desc_on"
app:key="filter_game_folders"
app:title="@string/filter_game_folders" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:summaryOff="@string/select_action_desc_off"