fixed about title crash

This commit is contained in:
izzy2lost
2025-10-25 13:16:42 -04:00
parent c88204f946
commit c717ec0c4c
4 changed files with 36 additions and 81150 deletions
File diff suppressed because one or more lines are too long
@@ -4,24 +4,15 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.izzy2lost.weeu.common.ui.components.ScreenContent
import com.izzy2lost.weeu.common.ui.localization.regionToString
import com.izzy2lost.weeu.common.ui.localization.tr
import com.izzy2lost.weeu.gamelist.cover.GameTitleMapper
import com.izzy2lost.weeu.nativeinterface.NativeGameTitles.Game
import java.time.LocalDate
import java.time.format.DateTimeFormatter
@@ -32,87 +23,26 @@ fun GameDetailsScreen(game: Game?, navigateBack: () -> Unit) {
if (game == null)
return
val context = LocalContext.current
var gameInfo by remember { mutableStateOf<GameInfo?>(null) }
LaunchedEffect(game.titleId) {
GameTitleMapper.initialize(context)
val titleIdHex = game.titleId.toString(16).uppercase().padStart(16, '0')
val gameId = GameTitleMapper.getGameCodeFromTitleId(titleIdHex)
if (gameId != null) {
gameInfo = GameInfoLoader.loadGameInfo(context, gameId)
}
}
ScreenContent(
appBarText = tr("About title"),
contentModifier = Modifier
.padding(16.dp)
.verticalScroll(rememberScrollState()),
contentModifier = Modifier.padding(16.dp),
contentVerticalArrangement = Arrangement.spacedBy(16.dp),
navigateBack = navigateBack,
) {
GameDetails(game, gameInfo)
GameDetails(game)
}
}
@Composable
fun GameDetails(game: Game, gameInfo: GameInfo?) {
fun GameDetails(game: Game) {
GameIcon(
game = game,
modifier = Modifier.size(128.dp),
)
// Game database information
if (gameInfo != null) {
gameInfo.title?.let {
TitleDetailsEntry(entryName = tr("Title"), entryData = it)
}
gameInfo.developer?.let {
TitleDetailsEntry(entryName = tr("Developer"), entryData = it)
}
gameInfo.publisher?.let {
TitleDetailsEntry(entryName = tr("Publisher"), entryData = it)
}
gameInfo.releaseDate?.let {
TitleDetailsEntry(entryName = tr("Release Date"), entryData = it)
}
gameInfo.genre?.let {
TitleDetailsEntry(entryName = tr("Genre"), entryData = it)
}
gameInfo.rating?.let {
TitleDetailsEntry(entryName = tr("Rating"), entryData = it)
}
if (gameInfo.ratingDescriptors.isNotEmpty()) {
TitleDetailsEntry(
entryName = tr("Content Descriptors"),
entryData = gameInfo.ratingDescriptors.joinToString(", ")
)
}
gameInfo.players?.let {
TitleDetailsEntry(entryName = tr("Players"), entryData = it)
}
gameInfo.wifiPlayers?.let {
TitleDetailsEntry(entryName = tr("Wi-Fi Players"), entryData = it)
}
if (gameInfo.wifiFeatures.isNotEmpty()) {
TitleDetailsEntry(
entryName = tr("Wi-Fi Features"),
entryData = gameInfo.wifiFeatures.joinToString(", ")
)
}
gameInfo.synopsis?.let {
TitleDetailsEntry(entryName = tr("Synopsis"), entryData = it)
}
}
// Local game information
TitleDetailsEntry(
entryName = tr("Title ID"),
entryData = game.titleId.toString(16).uppercase().padStart(16, '0')
)
TitleDetailsEntry(entryName = tr("Version"), entryData = game.version.toString())
TitleDetailsEntry(entryName = tr("DLC"), entryData = game.dlc.toString())
TitleDetailsEntry(entryName = tr("Title name"), entryData = game.name)
TitleDetailsEntry(entryName = tr("Title ID"), entryData = game.titleId)
TitleDetailsEntry(entryName = tr("Version"), entryData = game.version)
TitleDetailsEntry(entryName = tr("DLC"), entryData = game.dlc)
TitleDetailsEntry(
entryName = tr("You've played"),
entryData = getTimePlayed(game)
@@ -77,8 +77,9 @@ object GameInfoLoader {
}
"id" -> {
if (inGame) {
parser.next()
currentGameId = parser.text
if (parser.next() == XmlPullParser.TEXT) {
currentGameId = parser.text
}
}
}
"locale" -> {
@@ -88,26 +89,30 @@ object GameInfoLoader {
}
"title" -> {
if (inLocale) {
parser.next()
title = parser.text
if (parser.next() == XmlPullParser.TEXT) {
title = parser.text
}
}
}
"synopsis" -> {
if (inLocale) {
parser.next()
synopsis = parser.text
if (parser.next() == XmlPullParser.TEXT) {
synopsis = parser.text
}
}
}
"developer" -> {
if (inGame) {
parser.next()
developer = parser.text
if (parser.next() == XmlPullParser.TEXT) {
developer = parser.text
}
}
}
"publisher" -> {
if (inGame) {
parser.next()
publisher = parser.text
if (parser.next() == XmlPullParser.TEXT) {
publisher = parser.text
}
}
}
"date" -> {
@@ -120,8 +125,9 @@ object GameInfoLoader {
}
"genre" -> {
if (inGame) {
parser.next()
genre = parser.text
if (parser.next() == XmlPullParser.TEXT) {
genre = parser.text
}
}
}
"rating" -> {
@@ -134,8 +140,9 @@ object GameInfoLoader {
}
"descriptor" -> {
if (inRating) {
parser.next()
parser.text?.let { ratingDescriptors.add(it) }
if (parser.next() == XmlPullParser.TEXT) {
parser.text?.let { ratingDescriptors.add(it) }
}
}
}
"wi-fi" -> {
@@ -146,8 +153,9 @@ object GameInfoLoader {
}
"feature" -> {
if (inWifi) {
parser.next()
parser.text?.let { wifiFeatures.add(it) }
if (parser.next() == XmlPullParser.TEXT) {
parser.text?.let { wifiFeatures.add(it) }
}
}
}
"input" -> {
@@ -30,9 +30,11 @@ private inline fun <reified T : Any> NavGraphBuilder.composableGameScreen(
navController: NavController,
noinline content: @Composable (AnimatedContentScope.(NativeGameTitles.Game) -> Unit),
) {
composable<T> { backStackEntry ->
val parentEntry = navController.getBackStackEntry(GameListRoute)
val game = viewModel<GameViewModel>(parentEntry).game ?: return@composable
composable<T> {
val previousBackStackEntry =
navController.previousBackStackEntry ?: return@composable
val game =
viewModel<GameViewModel>(previousBackStackEntry).game ?: return@composable
content(game)
}
}