From 999fae76996a1692effcb7aaf1438306c3902de6 Mon Sep 17 00:00:00 2001
From: Emmanuel Hansen <emmausssss@gmail.com>
Date: Fri, 27 Oct 2023 07:55:12 +0000
Subject: [PATCH] android - fix crash when no user is available at launch

---
 .../android/viewmodels/MainViewModel.kt       | 12 ++++
 .../org/ryujinx/android/views/HomeViews.kt    | 59 ++++++++++++++-----
 .../org/ryujinx/android/views/MainView.kt     |  2 +-
 .../org/ryujinx/android/views/SettingViews.kt |  4 +-
 .../org/ryujinx/android/views/UserViews.kt    |  1 +
 5 files changed, 62 insertions(+), 16 deletions(-)

diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/MainViewModel.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/MainViewModel.kt
index c7d64ecc0..734267720 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/MainViewModel.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/MainViewModel.kt
@@ -37,6 +37,7 @@ class MainViewModel(val activity: MainActivity) {
     private var progress: MutableState<String>? = null
     private var progressValue: MutableState<Float>? = null
     private var showLoading: MutableState<Boolean>? = null
+    private var refreshUser: MutableState<Boolean>? = null
     var gameHost: GameHost? = null
         set(value) {
             field = value
@@ -213,4 +214,15 @@ class MainViewModel(val activity: MainActivity) {
         this.progress = progress
         gameHost?.setProgressStates(showLoading, progressValue, progress)
     }
+
+    fun setRefreshUserState(refreshUser: MutableState<Boolean>)
+    {
+        this.refreshUser = refreshUser
+    }
+
+    fun requestUserRefresh(){
+        refreshUser?.apply {
+            value = true
+        }
+    }
 }
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/HomeViews.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/HomeViews.kt
index 49b1a582f..bd1911ad0 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/HomeViews.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/HomeViews.kt
@@ -23,6 +23,7 @@ import androidx.compose.foundation.shape.CircleShape
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Add
 import androidx.compose.material.icons.filled.Menu
+import androidx.compose.material.icons.filled.Person
 import androidx.compose.material.icons.filled.Search
 import androidx.compose.material.icons.filled.Settings
 import androidx.compose.material3.AlertDialog
@@ -79,6 +80,7 @@ class HomeViews {
             viewModel: HomeViewModel = HomeViewModel(),
             navController: NavHostController? = null
         ) {
+            val native = RyujinxNative()
             val showAppActions = remember { mutableStateOf(false) }
             val showLoading = remember { mutableStateOf(false) }
             val openTitleUpdateDialog = remember { mutableStateOf(false) }
@@ -89,10 +91,27 @@ class HomeViews {
             val refresh = remember {
                 mutableStateOf(true)
             }
-            val native = RyujinxNative()
-            val user = native.userGetOpenedUser()
-            val decoder = Base64.getDecoder()
-            val pic = decoder.decode(native.userGetUserPicture(user))
+            val refreshUser = remember {
+                mutableStateOf(true)
+            }
+
+            viewModel.mainViewModel?.setRefreshUserState(refreshUser)
+            val user = remember {
+                mutableStateOf("")
+            }
+            val pic = remember {
+                mutableStateOf(ByteArray(0))
+            }
+            
+            if(refreshUser.value){
+                user.value = native.userGetOpenedUser()
+                if(user.value.isNotEmpty()) {
+                    val decoder = Base64.getDecoder()
+                    pic.value = decoder.decode(native.userGetUserPicture(user.value))
+                }
+
+                refreshUser.value = false;
+            }
             Scaffold(
                 modifier = Modifier.fillMaxSize(),
                 topBar = {
@@ -126,16 +145,28 @@ class HomeViews {
                             IconButton(onClick = {
                                 navController?.navigate("user")
                             }) {
-                                Image(
-                                    bitmap = BitmapFactory.decodeByteArray(pic, 0, pic.size)
-                                        .asImageBitmap(),
-                                    contentDescription = "user image",
-                                    contentScale = ContentScale.Crop,
-                                    modifier = Modifier
-                                        .padding(4.dp)
-                                        .size(52.dp)
-                                        .clip(CircleShape)
-                                )
+                                if(pic.value.isNotEmpty()) {
+                                    Image(
+                                        bitmap = BitmapFactory.decodeByteArray(
+                                            pic.value,
+                                            0,
+                                            pic.value.size
+                                        )
+                                            .asImageBitmap(),
+                                        contentDescription = "user image",
+                                        contentScale = ContentScale.Crop,
+                                        modifier = Modifier
+                                            .padding(4.dp)
+                                            .size(52.dp)
+                                            .clip(CircleShape)
+                                    )
+                                }
+                                else{
+                                    Icon(
+                                        Icons.Filled.Person,
+                                        contentDescription = "user"
+                                    )
+                                }
                             }
                             IconButton(
                                 onClick = {
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/MainView.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/MainView.kt
index 48df07647..b613cc51d 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/MainView.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/MainView.kt
@@ -22,7 +22,7 @@ class MainView {
                         SettingsViewModel(
                             navController,
                             mainViewModel.activity
-                        )
+                        ), mainViewModel
                     )
                 }
             }
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/SettingViews.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/SettingViews.kt
index 6cbf61680..5b28aad91 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/SettingViews.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/SettingViews.kt
@@ -54,6 +54,7 @@ import androidx.documentfile.provider.DocumentFile
 import com.anggrayudi.storage.file.extension
 import org.ryujinx.android.Helpers
 import org.ryujinx.android.MainActivity
+import org.ryujinx.android.viewmodels.MainViewModel
 import org.ryujinx.android.viewmodels.SettingsViewModel
 import org.ryujinx.android.viewmodels.VulkanDriverViewModel
 import kotlin.concurrent.thread
@@ -65,7 +66,7 @@ class SettingViews {
 
         @OptIn(ExperimentalMaterial3Api::class)
         @Composable
-        fun Main(settingsViewModel: SettingsViewModel) {
+        fun Main(settingsViewModel: SettingsViewModel, mainViewModel: MainViewModel) {
             val loaded = remember {
                 mutableStateOf(false)
             }
@@ -301,6 +302,7 @@ class SettingViews {
                                                         thread {
                                                             Helpers.importAppData(this, isImporting)
                                                             showImportCompletion.value = true
+                                                            mainViewModel.requestUserRefresh()
                                                         }
                                                     }
                                                 }, modifier = Modifier.padding(horizontal = 8.dp)) {
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/UserViews.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/UserViews.kt
index 2b54a7738..b41d17ea9 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/UserViews.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/UserViews.kt
@@ -162,6 +162,7 @@ class UserViews {
                                                 openedUser.value = user
                                                 openedUserPic.value = pic
                                                 openedUserName.value = name
+                                                viewModel?.requestUserRefresh()
                                             })
                                 )
                             }