mirror of
https://git.ryujinx.app/kenji-nx/ryujinx.git
synced 2025-12-15 10:37:04 +00:00
Version Badge added
This commit is contained in:
parent
7cc28d0242
commit
d73d82fbc0
1 changed files with 331 additions and 312 deletions
|
|
@ -93,6 +93,17 @@ class HomeViews {
|
||||||
const val ListImageSize = 150
|
const val ListImageSize = 150
|
||||||
const val GridImageSize = 300
|
const val GridImageSize = 300
|
||||||
|
|
||||||
|
// --- small version badge bottom left
|
||||||
|
@Composable
|
||||||
|
private fun VersionBadge(modifier: Modifier = Modifier) {
|
||||||
|
Text(
|
||||||
|
text = "v" + org.kenjinx.android.BuildConfig.VERSION_NAME,
|
||||||
|
style = MaterialTheme.typography.labelSmall,
|
||||||
|
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f),
|
||||||
|
modifier = modifier.padding(8.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun Home(
|
fun Home(
|
||||||
|
|
@ -125,45 +136,89 @@ class HomeViews {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
// --- Box around scaffold so we can overlay the badge
|
||||||
modifier = Modifier.fillMaxSize(),
|
Box(Modifier.fillMaxSize()) {
|
||||||
topBar = {
|
Scaffold(
|
||||||
Row(
|
modifier = Modifier.fillMaxSize(),
|
||||||
modifier = Modifier
|
topBar = {
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 16.dp, vertical = 8.dp)
|
|
||||||
.background(MaterialTheme.colorScheme.surface),
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.Start,
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||||
|
.background(MaterialTheme.colorScheme.surface),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier.padding(end = 8.dp)
|
|
||||||
) {
|
) {
|
||||||
Box(
|
Row(
|
||||||
modifier = Modifier
|
horizontalArrangement = Arrangement.Start,
|
||||||
.padding(end = 8.dp)
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
.size(56.dp)
|
modifier = Modifier.padding(end = 8.dp)
|
||||||
.clip(RoundedCornerShape(8.dp))
|
) {
|
||||||
.background(
|
Box(
|
||||||
if (refreshUser && viewModel.mainViewModel?.userViewModel?.openedUser?.userPicture?.isNotEmpty() == true) {
|
modifier = Modifier
|
||||||
Color.Transparent
|
.padding(end = 8.dp)
|
||||||
} else {
|
.size(56.dp)
|
||||||
MaterialTheme.colorScheme.surface
|
.clip(RoundedCornerShape(8.dp))
|
||||||
}
|
.background(
|
||||||
)
|
if (refreshUser && viewModel.mainViewModel?.userViewModel?.openedUser?.userPicture?.isNotEmpty() == true) {
|
||||||
.border(
|
Color.Transparent
|
||||||
width = 1.dp,
|
} else {
|
||||||
color = MaterialTheme.colorScheme.outline,
|
MaterialTheme.colorScheme.surface
|
||||||
shape = RoundedCornerShape(8.dp)
|
}
|
||||||
)
|
)
|
||||||
.clickable {
|
.border(
|
||||||
|
width = 1.dp,
|
||||||
|
color = MaterialTheme.colorScheme.outline,
|
||||||
|
shape = RoundedCornerShape(8.dp)
|
||||||
|
)
|
||||||
|
.clickable {
|
||||||
|
if (!isNavigating.value) {
|
||||||
|
isNavigating.value = true
|
||||||
|
val currentRoute = navController?.currentDestination?.route
|
||||||
|
if (currentRoute != "user") {
|
||||||
|
navController?.navigate("user") {
|
||||||
|
launchSingleTop = true
|
||||||
|
restoreState = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
delay(500)
|
||||||
|
isNavigating.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
if (refreshUser && viewModel.mainViewModel?.userViewModel?.openedUser?.userPicture?.isNotEmpty() == true) {
|
||||||
|
val pic = viewModel.mainViewModel.userViewModel.openedUser.userPicture
|
||||||
|
Image(
|
||||||
|
bitmap = BitmapFactory.decodeByteArray(
|
||||||
|
pic,
|
||||||
|
0,
|
||||||
|
pic?.size ?: 0
|
||||||
|
).asImageBitmap(),
|
||||||
|
contentDescription = "user image",
|
||||||
|
contentScale = ContentScale.Crop,
|
||||||
|
modifier = Modifier.fillMaxSize()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Icon(
|
||||||
|
Icons.Filled.Person,
|
||||||
|
contentDescription = "User",
|
||||||
|
modifier = Modifier.size(28.dp),
|
||||||
|
tint = MaterialTheme.colorScheme.onSurface
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
if (!isNavigating.value) {
|
if (!isNavigating.value) {
|
||||||
isNavigating.value = true
|
isNavigating.value = true
|
||||||
val currentRoute = navController?.currentDestination?.route
|
val currentRoute = navController?.currentDestination?.route
|
||||||
if (currentRoute != "user") {
|
if (currentRoute != "settings") {
|
||||||
navController?.navigate("user") {
|
navController?.navigate("settings") {
|
||||||
launchSingleTop = true
|
launchSingleTop = true
|
||||||
restoreState = true
|
restoreState = true
|
||||||
}
|
}
|
||||||
|
|
@ -174,153 +229,91 @@ class HomeViews {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
contentAlignment = Alignment.Center
|
modifier = Modifier
|
||||||
) {
|
.size(56.dp)
|
||||||
if (refreshUser && viewModel.mainViewModel?.userViewModel?.openedUser?.userPicture?.isNotEmpty() == true) {
|
.clip(RoundedCornerShape(8.dp))
|
||||||
val pic = viewModel.mainViewModel.userViewModel.openedUser.userPicture
|
.border(
|
||||||
Image(
|
width = 1.dp,
|
||||||
bitmap = BitmapFactory.decodeByteArray(
|
color = MaterialTheme.colorScheme.outline,
|
||||||
pic,
|
shape = RoundedCornerShape(8.dp)
|
||||||
0,
|
)
|
||||||
pic?.size ?: 0
|
) {
|
||||||
).asImageBitmap(),
|
Icon(Icons.Filled.Settings, contentDescription = "Settings")
|
||||||
contentDescription = "user image",
|
|
||||||
contentScale = ContentScale.Crop,
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Icon(
|
|
||||||
Icons.Filled.Person,
|
|
||||||
contentDescription = "User",
|
|
||||||
modifier = Modifier.size(28.dp),
|
|
||||||
tint = MaterialTheme.colorScheme.onSurface
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Settings
|
}
|
||||||
IconButton(
|
|
||||||
onClick = {
|
OutlinedTextField(
|
||||||
if (!isNavigating.value) {
|
value = query.value,
|
||||||
isNavigating.value = true
|
onValueChange = { query.value = it },
|
||||||
val currentRoute = navController?.currentDestination?.route
|
|
||||||
if (currentRoute != "settings") {
|
|
||||||
navController?.navigate("settings") {
|
|
||||||
launchSingleTop = true
|
|
||||||
restoreState = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
|
||||||
delay(500)
|
|
||||||
isNavigating.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(56.dp)
|
.weight(1f)
|
||||||
.clip(RoundedCornerShape(8.dp))
|
.height(56.dp),
|
||||||
.border(
|
placeholder = {
|
||||||
width = 1.dp,
|
Text("Search...", modifier = Modifier.padding(bottom = 4.dp))
|
||||||
color = MaterialTheme.colorScheme.outline,
|
},
|
||||||
shape = RoundedCornerShape(8.dp)
|
leadingIcon = { Icon(Icons.Filled.Search, contentDescription = "Search") },
|
||||||
)
|
singleLine = true,
|
||||||
) {
|
shape = RoundedCornerShape(8.dp),
|
||||||
Icon(Icons.Filled.Settings, contentDescription = "Settings")
|
colors = TextFieldDefaults.outlinedTextFieldColors(
|
||||||
}
|
focusedBorderColor = MaterialTheme.colorScheme.primary,
|
||||||
|
unfocusedBorderColor = MaterialTheme.colorScheme.outline
|
||||||
}
|
)
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
value = query.value,
|
|
||||||
onValueChange = { query.value = it },
|
|
||||||
modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.height(56.dp),
|
|
||||||
placeholder = {
|
|
||||||
Text("Search...", modifier = Modifier.padding(bottom = 4.dp))
|
|
||||||
},
|
|
||||||
leadingIcon = { Icon(Icons.Filled.Search, contentDescription = "Search") },
|
|
||||||
singleLine = true,
|
|
||||||
shape = RoundedCornerShape(8.dp),
|
|
||||||
colors = TextFieldDefaults.outlinedTextFieldColors(
|
|
||||||
focusedBorderColor = MaterialTheme.colorScheme.primary,
|
|
||||||
unfocusedBorderColor = MaterialTheme.colorScheme.outline
|
|
||||||
)
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
floatingActionButton = {
|
|
||||||
AnimatedVisibility(visible = isFabVisible) {
|
|
||||||
FloatingActionButton(
|
|
||||||
onClick = {
|
|
||||||
viewModel.requestReload()
|
|
||||||
viewModel.ensureReloadIfNecessary()
|
|
||||||
},
|
|
||||||
shape = MaterialTheme.shapes.small,
|
|
||||||
containerColor = MaterialTheme.colorScheme.tertiary
|
|
||||||
) {
|
|
||||||
Icon(Icons.Default.Refresh, contentDescription = "refresh")
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
floatingActionButton = {
|
||||||
floatingActionButtonPosition = FabPosition.End
|
AnimatedVisibility(visible = isFabVisible) {
|
||||||
) { contentPadding ->
|
FloatingActionButton(
|
||||||
Column(modifier = Modifier.padding(contentPadding)) {
|
onClick = {
|
||||||
Box {
|
viewModel.requestReload()
|
||||||
val list = remember { viewModel.gameList }
|
viewModel.ensureReloadIfNecessary()
|
||||||
val isLoading = remember { viewModel.isLoading }
|
},
|
||||||
|
shape = MaterialTheme.shapes.small,
|
||||||
|
containerColor = MaterialTheme.colorScheme.tertiary
|
||||||
|
) {
|
||||||
|
Icon(Icons.Default.Refresh, contentDescription = "refresh")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
floatingActionButtonPosition = FabPosition.End
|
||||||
|
) { contentPadding ->
|
||||||
|
Column(modifier = Modifier.padding(contentPadding)) {
|
||||||
|
Box {
|
||||||
|
val list = remember { viewModel.gameList }
|
||||||
|
val isLoading = remember { viewModel.isLoading }
|
||||||
|
|
||||||
viewModel.filter(query.value)
|
viewModel.filter(query.value)
|
||||||
|
|
||||||
if (!isPreview) {
|
if (!isPreview) {
|
||||||
val settings = QuickSettings(viewModel.activity!!)
|
val settings = QuickSettings(viewModel.activity!!)
|
||||||
if (isLoading.value) {
|
if (isLoading.value) {
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(64.dp)
|
.width(64.dp)
|
||||||
.align(Alignment.Center),
|
.align(Alignment.Center),
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
color = MaterialTheme.colorScheme.secondary,
|
||||||
trackColor = MaterialTheme.colorScheme.surfaceVariant
|
trackColor = MaterialTheme.colorScheme.surfaceVariant
|
||||||
)
|
)
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (settings.isGrid) {
|
|
||||||
val size = GridImageSize / Resources.getSystem().displayMetrics.density
|
|
||||||
LazyVerticalGrid(
|
|
||||||
columns = GridCells.Adaptive(minSize = (size + 4).dp),
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(4.dp)
|
|
||||||
.nestedScroll(nestedScrollConnection),
|
|
||||||
horizontalArrangement = Arrangement.SpaceEvenly
|
|
||||||
) {
|
|
||||||
items(list) {
|
|
||||||
it.titleName?.apply {
|
|
||||||
if (this.isNotEmpty() && (query.value.trim()
|
|
||||||
.isEmpty() || this.lowercase(Locale.getDefault())
|
|
||||||
.contains(query.value))) {
|
|
||||||
GridGameItem(
|
|
||||||
it,
|
|
||||||
viewModel,
|
|
||||||
showAppActions,
|
|
||||||
showLoading,
|
|
||||||
selectedModel,
|
|
||||||
showError
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LazyColumn(Modifier.fillMaxSize()) {
|
if (settings.isGrid) {
|
||||||
items(list) {
|
val size = GridImageSize / Resources.getSystem().displayMetrics.density
|
||||||
it.titleName?.apply {
|
LazyVerticalGrid(
|
||||||
if (this.isNotEmpty() && (query.value.trim()
|
columns = GridCells.Adaptive(minSize = (size + 4).dp),
|
||||||
.isEmpty() || this.lowercase(Locale.getDefault())
|
modifier = Modifier
|
||||||
.contains(query.value))) {
|
.fillMaxSize()
|
||||||
Box(modifier = Modifier.animateItemPlacement()) {
|
.padding(4.dp)
|
||||||
ListGameItem(
|
.nestedScroll(nestedScrollConnection),
|
||||||
|
horizontalArrangement = Arrangement.SpaceEvenly
|
||||||
|
) {
|
||||||
|
items(list) {
|
||||||
|
it.titleName?.apply {
|
||||||
|
if (this.isNotEmpty() && (query.value.trim()
|
||||||
|
.isEmpty() || this.lowercase(Locale.getDefault())
|
||||||
|
.contains(query.value))) {
|
||||||
|
GridGameItem(
|
||||||
it,
|
it,
|
||||||
viewModel,
|
viewModel,
|
||||||
showAppActions,
|
showAppActions,
|
||||||
|
|
@ -332,156 +325,182 @@ class HomeViews {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
LazyColumn(Modifier.fillMaxSize()) {
|
||||||
}
|
items(list) {
|
||||||
}
|
it.titleName?.apply {
|
||||||
}
|
if (this.isNotEmpty() && (query.value.trim()
|
||||||
}
|
.isEmpty() || this.lowercase(Locale.getDefault())
|
||||||
|
.contains(query.value))) {
|
||||||
SimpleAlertDialog.Loading(showDialog = showLoading)
|
Box(modifier = Modifier.animateItemPlacement()) {
|
||||||
SimpleAlertDialog.Custom(
|
ListGameItem(
|
||||||
showDialog = openTitleUpdateDialog,
|
it,
|
||||||
onDismissRequest = { openTitleUpdateDialog.value = false },
|
viewModel,
|
||||||
properties = DialogProperties(usePlatformDefaultWidth = false)
|
showAppActions,
|
||||||
) {
|
showLoading,
|
||||||
val titleId = viewModel.mainViewModel?.selected?.titleId ?: ""
|
selectedModel,
|
||||||
val name = viewModel.mainViewModel?.selected?.titleName ?: ""
|
showError
|
||||||
TitleUpdateViews.Main(titleId, name, openTitleUpdateDialog, canClose)
|
)
|
||||||
}
|
}
|
||||||
SimpleAlertDialog.Custom(
|
}
|
||||||
showDialog = openDlcDialog,
|
|
||||||
onDismissRequest = { openDlcDialog.value = false },
|
|
||||||
properties = DialogProperties(usePlatformDefaultWidth = false)
|
|
||||||
) {
|
|
||||||
val titleId = viewModel.mainViewModel?.selected?.titleId ?: ""
|
|
||||||
val name = viewModel.mainViewModel?.selected?.titleName ?: ""
|
|
||||||
DlcViews.Main(titleId, name, openDlcDialog, canClose)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viewModel.mainViewModel?.loadGameModel?.value != null)
|
|
||||||
LaunchedEffect(viewModel.mainViewModel.loadGameModel.value) {
|
|
||||||
if (viewModel.mainViewModel.bootPath.value ==
|
|
||||||
"gameItem_${viewModel.mainViewModel.loadGameModel.value!!.titleName}"
|
|
||||||
) {
|
|
||||||
viewModel.mainViewModel.bootPath.value = null
|
|
||||||
|
|
||||||
thread {
|
|
||||||
showLoading.value = true
|
|
||||||
val success = viewModel.mainViewModel.loadGame(
|
|
||||||
viewModel.mainViewModel.loadGameModel.value!!,
|
|
||||||
true,
|
|
||||||
viewModel.mainViewModel.forceNceAndPptc.value
|
|
||||||
) ?: false
|
|
||||||
if (success == 1) {
|
|
||||||
launchOnUiThread {
|
|
||||||
viewModel.mainViewModel.navigateToGame()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (success == -2)
|
|
||||||
showError.value = "Error loading update. Please re-add update file"
|
|
||||||
viewModel.mainViewModel.loadGameModel.value!!.close()
|
|
||||||
}
|
|
||||||
showLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showAppActions.value)
|
|
||||||
ModalBottomSheet(
|
|
||||||
content = {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.padding(8.dp),
|
|
||||||
horizontalArrangement = Arrangement.SpaceEvenly
|
|
||||||
) {
|
|
||||||
if (showAppActions.value) {
|
|
||||||
IconButton(onClick = {
|
|
||||||
if (viewModel.mainViewModel?.selected != null) {
|
|
||||||
thread {
|
|
||||||
showLoading.value = true
|
|
||||||
val success = viewModel.mainViewModel.loadGame(
|
|
||||||
viewModel.mainViewModel.selected!!
|
|
||||||
)
|
|
||||||
if (success == 1) {
|
|
||||||
launchOnUiThread {
|
|
||||||
viewModel.mainViewModel.navigateToGame()
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (success == -2)
|
|
||||||
showError.value =
|
|
||||||
"Error loading update. Please re-add update file"
|
|
||||||
viewModel.mainViewModel.selected!!.close()
|
|
||||||
}
|
}
|
||||||
showLoading.value = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}) {
|
|
||||||
Icon(
|
|
||||||
org.kenjinx.android.Icons.playArrow(MaterialTheme.colorScheme.onSurface),
|
|
||||||
contentDescription = "Run"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
val showAppMenu = remember { mutableStateOf(false) }
|
|
||||||
Box {
|
|
||||||
IconButton(onClick = { showAppMenu.value = true }) {
|
|
||||||
Icon(Icons.Filled.Menu, contentDescription = "Menu")
|
|
||||||
}
|
|
||||||
DropdownMenu(
|
|
||||||
expanded = showAppMenu.value,
|
|
||||||
onDismissRequest = { showAppMenu.value = false }
|
|
||||||
) {
|
|
||||||
DropdownMenuItem(
|
|
||||||
text = { Text(text = "Clear PPTC Cache") },
|
|
||||||
onClick = {
|
|
||||||
showAppMenu.value = false
|
|
||||||
viewModel.mainViewModel?.clearPptcCache(
|
|
||||||
viewModel.mainViewModel.selected?.titleId ?: ""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
DropdownMenuItem(
|
|
||||||
text = { Text(text = "Purge Shader Cache") },
|
|
||||||
onClick = {
|
|
||||||
showAppMenu.value = false
|
|
||||||
viewModel.mainViewModel?.purgeShaderCache(
|
|
||||||
viewModel.mainViewModel.selected?.titleId ?: ""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
DropdownMenuItem(
|
|
||||||
text = { Text(text = "Delete All Cache") },
|
|
||||||
onClick = {
|
|
||||||
showAppMenu.value = false
|
|
||||||
viewModel.mainViewModel?.deleteCache(
|
|
||||||
viewModel.mainViewModel.selected?.titleId ?: ""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
DropdownMenuItem(
|
|
||||||
text = { Text(text = "Manage Updates") },
|
|
||||||
onClick = {
|
|
||||||
showAppMenu.value = false
|
|
||||||
openTitleUpdateDialog.value = true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
DropdownMenuItem(
|
|
||||||
text = { Text(text = "Manage DLC") },
|
|
||||||
onClick = {
|
|
||||||
showAppMenu.value = false
|
|
||||||
openDlcDialog.value = true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
onDismissRequest = {
|
|
||||||
showAppActions.value = false
|
|
||||||
selectedModel.value = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SimpleAlertDialog.Loading(showDialog = showLoading)
|
||||||
|
SimpleAlertDialog.Custom(
|
||||||
|
showDialog = openTitleUpdateDialog,
|
||||||
|
onDismissRequest = { openTitleUpdateDialog.value = false },
|
||||||
|
properties = DialogProperties(usePlatformDefaultWidth = false)
|
||||||
|
) {
|
||||||
|
val titleId = viewModel.mainViewModel?.selected?.titleId ?: ""
|
||||||
|
val name = viewModel.mainViewModel?.selected?.titleName ?: ""
|
||||||
|
TitleUpdateViews.Main(titleId, name, openTitleUpdateDialog, canClose)
|
||||||
|
}
|
||||||
|
SimpleAlertDialog.Custom(
|
||||||
|
showDialog = openDlcDialog,
|
||||||
|
onDismissRequest = { openDlcDialog.value = false },
|
||||||
|
properties = DialogProperties(usePlatformDefaultWidth = false)
|
||||||
|
) {
|
||||||
|
val titleId = viewModel.mainViewModel?.selected?.titleId ?: ""
|
||||||
|
val name = viewModel.mainViewModel?.selected?.titleName ?: ""
|
||||||
|
DlcViews.Main(titleId, name, openDlcDialog, canClose)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewModel.mainViewModel?.loadGameModel?.value != null)
|
||||||
|
LaunchedEffect(viewModel.mainViewModel.loadGameModel.value) {
|
||||||
|
if (viewModel.mainViewModel.bootPath.value ==
|
||||||
|
"gameItem_${viewModel.mainViewModel.loadGameModel.value!!.titleName}"
|
||||||
|
) {
|
||||||
|
viewModel.mainViewModel.bootPath.value = null
|
||||||
|
|
||||||
|
thread {
|
||||||
|
showLoading.value = true
|
||||||
|
val success = viewModel.mainViewModel.loadGame(
|
||||||
|
viewModel.mainViewModel.loadGameModel.value!!,
|
||||||
|
true,
|
||||||
|
viewModel.mainViewModel.forceNceAndPptc.value
|
||||||
|
) ?: false
|
||||||
|
if (success == 1) {
|
||||||
|
launchOnUiThread {
|
||||||
|
viewModel.mainViewModel.navigateToGame()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (success == -2)
|
||||||
|
showError.value = "Error loading update. Please re-add update file"
|
||||||
|
viewModel.mainViewModel.loadGameModel.value!!.close()
|
||||||
|
}
|
||||||
|
showLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showAppActions.value)
|
||||||
|
ModalBottomSheet(
|
||||||
|
content = {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.padding(8.dp),
|
||||||
|
horizontalArrangement = Arrangement.SpaceEvenly
|
||||||
|
) {
|
||||||
|
if (showAppActions.value) {
|
||||||
|
IconButton(onClick = {
|
||||||
|
if (viewModel.mainViewModel?.selected != null) {
|
||||||
|
thread {
|
||||||
|
showLoading.value = true
|
||||||
|
val success = viewModel.mainViewModel.loadGame(
|
||||||
|
viewModel.mainViewModel.selected!!
|
||||||
|
)
|
||||||
|
if (success == 1) {
|
||||||
|
launchOnUiThread {
|
||||||
|
viewModel.mainViewModel.navigateToGame()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (success == -2)
|
||||||
|
showError.value =
|
||||||
|
"Error loading update. Please re-add update file"
|
||||||
|
viewModel.mainViewModel.selected!!.close()
|
||||||
|
}
|
||||||
|
showLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Icon(
|
||||||
|
org.kenjinx.android.Icons.playArrow(MaterialTheme.colorScheme.onSurface),
|
||||||
|
contentDescription = "Run"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val showAppMenu = remember { mutableStateOf(false) }
|
||||||
|
Box {
|
||||||
|
IconButton(onClick = { showAppMenu.value = true }) {
|
||||||
|
Icon(Icons.Filled.Menu, contentDescription = "Menu")
|
||||||
|
}
|
||||||
|
DropdownMenu(
|
||||||
|
expanded = showAppMenu.value,
|
||||||
|
onDismissRequest = { showAppMenu.value = false }
|
||||||
|
) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(text = "Clear PPTC Cache") },
|
||||||
|
onClick = {
|
||||||
|
showAppMenu.value = false
|
||||||
|
viewModel.mainViewModel?.clearPptcCache(
|
||||||
|
viewModel.mainViewModel.selected?.titleId ?: ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(text = "Purge Shader Cache") },
|
||||||
|
onClick = {
|
||||||
|
showAppMenu.value = false
|
||||||
|
viewModel.mainViewModel?.purgeShaderCache(
|
||||||
|
viewModel.mainViewModel.selected?.titleId ?: ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(text = "Delete All Cache") },
|
||||||
|
onClick = {
|
||||||
|
showAppMenu.value = false
|
||||||
|
viewModel.mainViewModel?.deleteCache(
|
||||||
|
viewModel.mainViewModel.selected?.titleId ?: ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(text = "Manage Updates") },
|
||||||
|
onClick = {
|
||||||
|
showAppMenu.value = false
|
||||||
|
openTitleUpdateDialog.value = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(text = "Manage DLC") },
|
||||||
|
onClick = {
|
||||||
|
showAppMenu.value = false
|
||||||
|
openDlcDialog.value = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDismissRequest = {
|
||||||
|
showAppActions.value = false
|
||||||
|
selectedModel.value = null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// --- Version badge bottom left above the entire content
|
||||||
|
VersionBadge(
|
||||||
|
modifier = Modifier.align(Alignment.BottomStart)
|
||||||
)
|
)
|
||||||
|
} // End of box
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue