summaryrefslogtreecommitdiff
path: root/src/android/app
diff options
context:
space:
mode:
authorGravatar Charles Lombardo2023-05-02 05:58:03 -0400
committerGravatar bunnei2023-06-03 00:05:59 -0700
commit65dc35a1a5484f5e7b9a0770fa5b536782a87fbe (patch)
tree06d54d383ab12ae3d3ddbc84c5ee0bc8b8c16fcc /src/android/app
parentandroid: Update to Kotlin 1.8.21 (diff)
downloadyuzu-65dc35a1a5484f5e7b9a0770fa5b536782a87fbe.tar.gz
yuzu-65dc35a1a5484f5e7b9a0770fa5b536782a87fbe.tar.xz
yuzu-65dc35a1a5484f5e7b9a0770fa5b536782a87fbe.zip
android: Game data cache
Diffstat (limited to 'src/android/app')
-rw-r--r--src/android/app/build.gradle.kts2
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt1
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt14
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt28
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt11
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt1
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt21
-rw-r--r--src/android/app/src/main/res/layout/fragment_games.xml2
8 files changed, 63 insertions, 17 deletions
diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts
index ea13b6d0e..a9790b200 100644
--- a/src/android/app/build.gradle.kts
+++ b/src/android/app/build.gradle.kts
@@ -2,6 +2,7 @@ plugins {
2 id("com.android.application") 2 id("com.android.application")
3 id("org.jetbrains.kotlin.android") 3 id("org.jetbrains.kotlin.android")
4 id("kotlin-parcelize") 4 id("kotlin-parcelize")
5 kotlin("plugin.serialization") version "1.8.21"
5} 6}
6 7
7/** 8/**
@@ -164,6 +165,7 @@ dependencies {
164 implementation("androidx.navigation:navigation-fragment-ktx:2.5.3") 165 implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
165 implementation("androidx.navigation:navigation-ui-ktx:2.5.3") 166 implementation("androidx.navigation:navigation-ui-ktx:2.5.3")
166 implementation("info.debatty:java-string-similarity:2.0.0") 167 implementation("info.debatty:java-string-similarity:2.0.0")
168 implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
167} 169}
168 170
169fun getVersion(): String { 171fun getVersion(): String {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
index b9f975e2b..a9653475f 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
@@ -100,7 +100,6 @@ class GameAdapter(private val activity: AppCompatActivity) :
100 return oldItem.gameId == newItem.gameId 100 return oldItem.gameId == newItem.gameId
101 } 101 }
102 102
103 @SuppressLint("DiffUtilEquals")
104 override fun areContentsTheSame(oldItem: Game, newItem: Game): Boolean { 103 override fun areContentsTheSame(oldItem: Game, newItem: Game): Boolean {
105 return oldItem == newItem 104 return oldItem == newItem
106 } 105 }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt
index c5cde9d05..2a17653b2 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt
@@ -5,9 +5,11 @@ package org.yuzu.yuzu_emu.model
5 5
6import android.os.Parcelable 6import android.os.Parcelable
7import kotlinx.parcelize.Parcelize 7import kotlinx.parcelize.Parcelize
8import kotlinx.serialization.Serializable
8import java.util.HashSet 9import java.util.HashSet
9 10
10@Parcelize 11@Parcelize
12@Serializable
11class Game( 13class Game(
12 val title: String, 14 val title: String,
13 val description: String, 15 val description: String,
@@ -19,6 +21,18 @@ class Game(
19 val keyAddedToLibraryTime get() = "${gameId}_AddedToLibraryTime" 21 val keyAddedToLibraryTime get() = "${gameId}_AddedToLibraryTime"
20 val keyLastPlayedTime get() = "${gameId}_LastPlayed" 22 val keyLastPlayedTime get() = "${gameId}_LastPlayed"
21 23
24 override fun equals(other: Any?): Boolean {
25 if (other !is Game)
26 return false
27
28 return title == other.title
29 && description == other.description
30 && regions == other.regions
31 && path == other.path
32 && gameId == other.gameId
33 && company == other.company
34 }
35
22 companion object { 36 companion object {
23 val extensions: Set<String> = HashSet( 37 val extensions: Set<String> = HashSet(
24 listOf(".xci", ".nsp", ".nca", ".nro") 38 listOf(".xci", ".nsp", ".nca", ".nro")
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt
index 1d0846b08..5a35b14c9 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt
@@ -7,11 +7,16 @@ import androidx.lifecycle.LiveData
7import androidx.lifecycle.MutableLiveData 7import androidx.lifecycle.MutableLiveData
8import androidx.lifecycle.ViewModel 8import androidx.lifecycle.ViewModel
9import androidx.lifecycle.viewModelScope 9import androidx.lifecycle.viewModelScope
10import androidx.preference.PreferenceManager
10import kotlinx.coroutines.Dispatchers 11import kotlinx.coroutines.Dispatchers
11import kotlinx.coroutines.launch 12import kotlinx.coroutines.launch
12import kotlinx.coroutines.withContext 13import kotlinx.coroutines.withContext
14import kotlinx.serialization.decodeFromString
15import kotlinx.serialization.json.Json
13import org.yuzu.yuzu_emu.NativeLibrary 16import org.yuzu.yuzu_emu.NativeLibrary
17import org.yuzu.yuzu_emu.YuzuApplication
14import org.yuzu.yuzu_emu.utils.GameHelper 18import org.yuzu.yuzu_emu.utils.GameHelper
19import java.util.Locale
15 20
16class GamesViewModel : ViewModel() { 21class GamesViewModel : ViewModel() {
17 private val _games = MutableLiveData<List<Game>>(emptyList()) 22 private val _games = MutableLiveData<List<Game>>(emptyList())
@@ -33,9 +38,30 @@ class GamesViewModel : ViewModel() {
33 val searchFocused: LiveData<Boolean> get() = _searchFocused 38 val searchFocused: LiveData<Boolean> get() = _searchFocused
34 39
35 init { 40 init {
41 // Retrieve list of cached games
42 val storedGames = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
43 .getStringSet(GameHelper.KEY_GAMES, emptySet())
44 if (storedGames!!.isNotEmpty()) {
45 val deserializedGames = mutableSetOf<Game>()
46 storedGames.forEach {
47 deserializedGames.add(Json.decodeFromString(it))
48 }
49 setGames(deserializedGames.toList())
50 }
36 reloadGames(false) 51 reloadGames(false)
37 } 52 }
38 53
54 fun setGames(games: List<Game>) {
55 val sortedList = games.sortedWith(
56 compareBy(
57 { it.title.lowercase(Locale.getDefault()) },
58 { it.path }
59 )
60 )
61
62 _games.postValue(sortedList)
63 }
64
39 fun setSearchedGames(games: List<Game>) { 65 fun setSearchedGames(games: List<Game>) {
40 _searchedGames.postValue(games) 66 _searchedGames.postValue(games)
41 } 67 }
@@ -60,7 +86,7 @@ class GamesViewModel : ViewModel() {
60 viewModelScope.launch { 86 viewModelScope.launch {
61 withContext(Dispatchers.IO) { 87 withContext(Dispatchers.IO) {
62 NativeLibrary.resetRomMetadata() 88 NativeLibrary.resetRomMetadata()
63 _games.postValue(GameHelper.getGames()) 89 setGames(GameHelper.getGames())
64 _isReloading.postValue(false) 90 _isReloading.postValue(false)
65 91
66 if (directoryChanged) { 92 if (directoryChanged) {
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 07d0cd3d8..afabfb2b9 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
@@ -20,10 +20,8 @@ import org.yuzu.yuzu_emu.R
20import org.yuzu.yuzu_emu.adapters.GameAdapter 20import org.yuzu.yuzu_emu.adapters.GameAdapter
21import org.yuzu.yuzu_emu.databinding.FragmentGamesBinding 21import org.yuzu.yuzu_emu.databinding.FragmentGamesBinding
22import org.yuzu.yuzu_emu.layout.AutofitGridLayoutManager 22import org.yuzu.yuzu_emu.layout.AutofitGridLayoutManager
23import org.yuzu.yuzu_emu.model.Game
24import org.yuzu.yuzu_emu.model.GamesViewModel 23import org.yuzu.yuzu_emu.model.GamesViewModel
25import org.yuzu.yuzu_emu.model.HomeViewModel 24import org.yuzu.yuzu_emu.model.HomeViewModel
26import java.util.Locale
27 25
28class GamesFragment : Fragment() { 26class GamesFragment : Fragment() {
29 private var _binding: FragmentGamesBinding? = null 27 private var _binding: FragmentGamesBinding? = null
@@ -81,7 +79,7 @@ class GamesFragment : Fragment() {
81 binding.swipeRefresh.isRefreshing = isReloading 79 binding.swipeRefresh.isRefreshing = isReloading
82 } 80 }
83 gamesViewModel.games.observe(viewLifecycleOwner) { 81 gamesViewModel.games.observe(viewLifecycleOwner) {
84 submitGamesList(it) 82 (binding.gridGames.adapter as GameAdapter).submitList(it)
85 if (it.isEmpty()) { 83 if (it.isEmpty()) {
86 binding.noticeText.visibility = View.VISIBLE 84 binding.noticeText.visibility = View.VISIBLE
87 } else { 85 } else {
@@ -91,7 +89,7 @@ class GamesFragment : Fragment() {
91 89
92 gamesViewModel.shouldSwapData.observe(viewLifecycleOwner) { shouldSwapData -> 90 gamesViewModel.shouldSwapData.observe(viewLifecycleOwner) { shouldSwapData ->
93 if (shouldSwapData) { 91 if (shouldSwapData) {
94 submitGamesList(gamesViewModel.games.value!!) 92 (binding.gridGames.adapter as GameAdapter).submitList(gamesViewModel.games.value!!)
95 gamesViewModel.setShouldSwapData(false) 93 gamesViewModel.setShouldSwapData(false)
96 } 94 }
97 } 95 }
@@ -115,11 +113,6 @@ class GamesFragment : Fragment() {
115 } 113 }
116 } 114 }
117 115
118 private fun submitGamesList(gameList: List<Game>) {
119 val sortedList = gameList.sortedBy { it.title.lowercase(Locale.getDefault()) }
120 (binding.gridGames.adapter as GameAdapter).submitList(sortedList)
121 }
122
123 override fun onDestroyView() { 116 override fun onDestroyView() {
124 super.onDestroyView() 117 super.onDestroyView()
125 _binding = null 118 _binding = null
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 b2499168e..f8f275b41 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
@@ -25,7 +25,6 @@ import androidx.navigation.ui.setupWithNavController
25import androidx.preference.PreferenceManager 25import androidx.preference.PreferenceManager
26import com.google.android.material.color.MaterialColors 26import com.google.android.material.color.MaterialColors
27import com.google.android.material.dialog.MaterialAlertDialogBuilder 27import com.google.android.material.dialog.MaterialAlertDialogBuilder
28import com.google.android.material.elevation.ElevationOverlayProvider
29import com.google.android.material.navigation.NavigationBarView 28import com.google.android.material.navigation.NavigationBarView
30import kotlinx.coroutines.Dispatchers 29import kotlinx.coroutines.Dispatchers
31import kotlinx.coroutines.launch 30import kotlinx.coroutines.launch
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt
index 9dd43343f..ba6b5783e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt
@@ -6,19 +6,22 @@ package org.yuzu.yuzu_emu.utils
6import android.content.SharedPreferences 6import android.content.SharedPreferences
7import android.net.Uri 7import android.net.Uri
8import androidx.preference.PreferenceManager 8import androidx.preference.PreferenceManager
9import kotlinx.serialization.decodeFromString
10import kotlinx.serialization.encodeToString
11import kotlinx.serialization.json.Json
9import org.yuzu.yuzu_emu.NativeLibrary 12import org.yuzu.yuzu_emu.NativeLibrary
10import org.yuzu.yuzu_emu.YuzuApplication 13import org.yuzu.yuzu_emu.YuzuApplication
11import org.yuzu.yuzu_emu.model.Game 14import org.yuzu.yuzu_emu.model.Game
12import java.util.* 15import java.util.*
13import kotlin.collections.ArrayList
14 16
15object GameHelper { 17object GameHelper {
16 const val KEY_GAME_PATH = "game_path" 18 const val KEY_GAME_PATH = "game_path"
19 const val KEY_GAMES = "Games"
17 20
18 private lateinit var preferences: SharedPreferences 21 private lateinit var preferences: SharedPreferences
19 22
20 fun getGames(): ArrayList<Game> { 23 fun getGames(): List<Game> {
21 val games = ArrayList<Game>() 24 val games = mutableListOf<Game>()
22 val context = YuzuApplication.appContext 25 val context = YuzuApplication.appContext
23 val gamesDir = 26 val gamesDir =
24 PreferenceManager.getDefaultSharedPreferences(context).getString(KEY_GAME_PATH, "") 27 PreferenceManager.getDefaultSharedPreferences(context).getString(KEY_GAME_PATH, "")
@@ -44,7 +47,17 @@ object GameHelper {
44 } 47 }
45 } 48 }
46 49
47 return games 50 // Cache list of games found on disk
51 val serializedGames = mutableSetOf<String>()
52 games.forEach {
53 serializedGames.add(Json.encodeToString(it))
54 }
55 preferences.edit()
56 .remove(KEY_GAMES)
57 .putStringSet(KEY_GAMES, serializedGames)
58 .apply()
59
60 return games.toList()
48 } 61 }
49 62
50 private fun getGame(filePath: String): Game { 63 private fun getGame(filePath: String): Game {
diff --git a/src/android/app/src/main/res/layout/fragment_games.xml b/src/android/app/src/main/res/layout/fragment_games.xml
index 8b6d0b3b6..a0568668a 100644
--- a/src/android/app/src/main/res/layout/fragment_games.xml
+++ b/src/android/app/src/main/res/layout/fragment_games.xml
@@ -20,7 +20,7 @@
20 android:gravity="center" 20 android:gravity="center"
21 android:padding="@dimen/spacing_large" 21 android:padding="@dimen/spacing_large"
22 android:text="@string/empty_gamelist" 22 android:text="@string/empty_gamelist"
23 tools:visibility="gone" /> 23 android:visibility="gone" />
24 24
25 <androidx.recyclerview.widget.RecyclerView 25 <androidx.recyclerview.widget.RecyclerView
26 android:id="@+id/grid_games" 26 android:id="@+id/grid_games"