From 77f186ad226f47ec2956e3769f55f22506b80864 Mon Sep 17 00:00:00 2001 From: Joshua Tam <297250+joshuatam@users.noreply.github.com> Date: Fri, 9 Jan 2026 21:36:16 +0800 Subject: [PATCH 1/4] Improves DLC selection and download status Adds a "Select All/Deselect All" button to the game manager dialog for easier DLC selection. Shows installed DLC even if a download is in progress for the base game. This improves the user experience by allowing users to quickly select or deselect all available DLCs and clarifies the download status of apps. --- .../ui/component/dialog/GameManagerDialog.kt | 42 +++++++++++++++++++ .../library/appscreen/SteamAppScreen.kt | 3 +- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/app/gamenative/ui/component/dialog/GameManagerDialog.kt b/app/src/main/java/app/gamenative/ui/component/dialog/GameManagerDialog.kt index 2fa0af8ccb..169bb2872e 100644 --- a/app/src/main/java/app/gamenative/ui/component/dialog/GameManagerDialog.kt +++ b/app/src/main/java/app/gamenative/ui/component/dialog/GameManagerDialog.kt @@ -18,6 +18,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Button import androidx.compose.material3.Checkbox import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.ListItem import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface @@ -230,6 +231,18 @@ fun GameManagerDialog( ) } + val selectableAppIds by remember(enabledAppIds.toMap()) { + derivedStateOf { + enabledAppIds.filter { it.value }.keys.toList() + } + } + + val allSelectableSelected by remember(selectedAppIds.toMap(), selectableAppIds) { + derivedStateOf { + selectableAppIds.isNotEmpty() && selectableAppIds.all { selectedAppIds[it] == true } + } + } + val installSizeInfo by remember(downloadableDepots.keys.toSet(), selectedAppIds.toMap(), enabledAppIds.toMap()) { derivedStateOf { getInstallSizeInfo() } } @@ -372,6 +385,29 @@ fun GameManagerDialog( Column( modifier = Modifier.fillMaxWidth() ) { + // Select All toggle + if (selectableAppIds.isNotEmpty()) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp), + horizontalArrangement = Arrangement.End + ) { + Button( + onClick = { + val newState = !allSelectableSelected + selectableAppIds.forEach { appId -> + selectedAppIds[appId] = newState + } + } + ) { + Text( + text = if (allSelectableSelected) "Deselect all" else "Select all" + ) + } + } + } + allDownloadableApps.forEach { (dlcAppId, depotInfo) -> val checked = selectedAppIds[dlcAppId] ?: false val enabled = enabledAppIds[dlcAppId] ?: false @@ -406,6 +442,12 @@ fun GameManagerDialog( selectedAppIds[dlcAppId] = !checked } ) + + HorizontalDivider( + modifier = Modifier.padding(horizontal = 16.dp), + thickness = 0.5.dp, + color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f) + ) } } diff --git a/app/src/main/java/app/gamenative/ui/screen/library/appscreen/SteamAppScreen.kt b/app/src/main/java/app/gamenative/ui/screen/library/appscreen/SteamAppScreen.kt index 6804d7685f..63f12d4667 100644 --- a/app/src/main/java/app/gamenative/ui/screen/library/appscreen/SteamAppScreen.kt +++ b/app/src/main/java/app/gamenative/ui/screen/library/appscreen/SteamAppScreen.kt @@ -609,8 +609,9 @@ class SteamAppScreen : BaseAppScreen() { val gameId = libraryItem.gameId val appId = libraryItem.appId val appInfo = SteamService.getAppInfoOf(gameId) ?: return emptyList() + val isDownloadInProgress = SteamService.getDownloadingAppInfoOf(gameId) != null - if (!isInstalled) { + if (!isInstalled || isDownloadInProgress) { return emptyList() } From 403d7fbc212fafe41285316bde8d22fb62bc755c Mon Sep 17 00:00:00 2001 From: Joshua Tam <297250+joshuatam@users.noreply.github.com> Date: Fri, 9 Jan 2026 22:51:00 +0800 Subject: [PATCH 2/4] Corrects DLC installation logic in game manager Addresses an issue where DLCs were not correctly identified as installed, particularly concerning optional and indirect DLCs. Updates the logic to accurately determine the installation state of DLCs based on their type and installation status, ensuring a more reliable user experience. --- .../ui/component/dialog/GameManagerDialog.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/app/gamenative/ui/component/dialog/GameManagerDialog.kt b/app/src/main/java/app/gamenative/ui/component/dialog/GameManagerDialog.kt index 169bb2872e..a2505b8310 100644 --- a/app/src/main/java/app/gamenative/ui/component/dialog/GameManagerDialog.kt +++ b/app/src/main/java/app/gamenative/ui/component/dialog/GameManagerDialog.kt @@ -110,7 +110,13 @@ fun GameManagerDialog( allDownloadableApps.clear() // Get Downloadable Depots - downloadableDepots.putAll(SteamService.getDownloadableDepots(gameId)) + val allPossibleDownloadableDepots = SteamService.getDownloadableDepots(gameId) + downloadableDepots.putAll(allPossibleDownloadableDepots) + + // Get Optional DLC IDs + val optionalDlcIds = allPossibleDownloadableDepots + .filter { it.value.optionalDlcId == it.value.dlcAppId } + .map { it.value.dlcAppId } // Add DLCs downloadableDepots @@ -124,7 +130,11 @@ fun GameManagerDialog( .forEach { (_, depotInfo) -> allDownloadableApps.add(Pair(depotInfo.dlcAppId, depotInfo)) val installed = SteamService.getInstalledApp(depotInfo.dlcAppId) - selectedAppIds[depotInfo.dlcAppId] = !indirectDlcAppIds.contains(depotInfo.dlcAppId) || installedDlcIds.contains(depotInfo.dlcAppId) || installed != null + selectedAppIds[depotInfo.dlcAppId] = + installed != null || // For installed Base Game and Indirect DLC App + installedDlcIds.contains(depotInfo.dlcAppId) || // For installed DLC from Main Depot + ( !indirectDlcAppIds.contains(depotInfo.dlcAppId) && !optionalDlcIds.contains(depotInfo.dlcAppId) ) // Not in indirect DLC and not in optional DLC ids + enabledAppIds[depotInfo.dlcAppId] = !installedDlcIds.contains(depotInfo.dlcAppId) && installed == null } From d28fcf6a6c96b3da5f96f9d0f0ed9460da7abb5d Mon Sep 17 00:00:00 2001 From: Joshua Tam <297250+joshuatam@users.noreply.github.com> Date: Fri, 9 Jan 2026 23:09:04 +0800 Subject: [PATCH 3/4] does not delete app_info data when login or steam login has error --- app/src/main/java/app/gamenative/service/SteamService.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/app/gamenative/service/SteamService.kt b/app/src/main/java/app/gamenative/service/SteamService.kt index 46d683bf2b..9f096b9f43 100644 --- a/app/src/main/java/app/gamenative/service/SteamService.kt +++ b/app/src/main/java/app/gamenative/service/SteamService.kt @@ -2036,7 +2036,6 @@ class SteamService : Service(), IChallengeUrlChanged { with(instance!!) { scope.launch { db.withTransaction { - appDao.deleteAll() changeNumbersDao.deleteAll() fileChangeListsDao.deleteAll() licenseDao.deleteAll() From 6f51f24dae77e987ae3113c4211caffa862d84ab Mon Sep 17 00:00:00 2001 From: Joshua Tam <297250+joshuatam@users.noreply.github.com> Date: Sat, 10 Jan 2026 18:22:06 +0800 Subject: [PATCH 4/4] updates JavaSteam to add delay on large depots size --- app/build.gradle.kts | 4 ++-- gradle/libs.versions.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 0a62af6625..ff3a2d438f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -228,8 +228,8 @@ dependencies { // JavaSteam val localBuild = false // Change to 'true' needed when building JavaSteam manually if (localBuild) { - implementation(files("../../JavaSteam/build/libs/javasteam-1.8.0-5-SNAPSHOT.jar")) - implementation(files("../../JavaSteam/javasteam-depotdownloader/build/libs/javasteam-depotdownloader-1.8.0-5-SNAPSHOT.jar")) + implementation(files("../../JavaSteam/build/libs/javasteam-1.8.0-6-SNAPSHOT.jar")) + implementation(files("../../JavaSteam/javasteam-depotdownloader/build/libs/javasteam-depotdownloader-1.8.0-6-SNAPSHOT.jar")) implementation(libs.bundles.javasteam.dev) } else { implementation(libs.javasteam) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 55c18a31b1..fc5d800b5f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ dataStore = "1.1.2" # https://mvnrepository.com/artifact/androidx.datastore/data espressoCore = "3.6.1" # https://mvnrepository.com/artifact/androidx.test.espresso/espresso-core feature-delivery = "2.1.0" # https://mvnrepository.com/artifact/com.google.android.play/feature-delivery hiltNavigationCompose = "1.2.0" # https://mvnrepository.com/artifact/androidx.hilt/hilt-navigation-compose -javasteam = "1.8.0-5-SNAPSHOT" # https://mvnrepository.com/artifact/in.dragonbra/javasteam +javasteam = "1.8.0-6-SNAPSHOT" # https://mvnrepository.com/artifact/in.dragonbra/javasteam json = "1.8.0" # https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-serialization-json junit = "4.13.2" # https://mvnrepository.com/artifact/junit/junit junitVersion = "1.2.1" # https://mvnrepository.com/artifact/androidx.test.ext/junit