Add the basic framework to assign game folder
This commit is contained in:
parent
35fb874a42
commit
3921099c53
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue