Skip to content

Commit 92e2244

Browse files
authored
Merge pull request #145 from oxters168/library-bug-fixes
Library Bugs and Rugs
2 parents cd3433d + 40ed0f9 commit 92e2244

17 files changed

+422
-137
lines changed

app/build.gradle.kts

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ android {
4242
minSdk = 29
4343
targetSdk = 34
4444

45-
versionCode = 3
46-
versionName = "1.2.0"
45+
versionCode = 4
46+
versionName = "1.3.0"
4747

4848
buildConfigField("boolean", "GOLD", "false")
4949
val iconValue = "@mipmap/ic_launcher"

app/src/main/java/com/OxGames/Pluvia/PrefManager.kt

+11
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import androidx.datastore.preferences.core.stringPreferencesKey
1414
import androidx.datastore.preferences.preferencesDataStore
1515
import com.OxGames.Pluvia.enums.AppTheme
1616
import com.OxGames.Pluvia.service.SteamService
17+
import com.OxGames.Pluvia.ui.enums.AppFilter
1718
import com.OxGames.Pluvia.ui.enums.HomeDestination
1819
import com.OxGames.Pluvia.ui.enums.Orientation
1920
import com.materialkolor.PaletteStyle
@@ -356,6 +357,16 @@ object PrefManager {
356357
/**
357358
* Get or Set the last known Persona State. See [EPersonaState]
358359
*/
360+
private val LIBRARY_FILTER = intPreferencesKey("library_filter")
361+
var libraryFilter: EnumSet<AppFilter>
362+
get() {
363+
val value = getPref(LIBRARY_FILTER, AppFilter.toFlags(EnumSet.of(AppFilter.GAME)))
364+
return AppFilter.fromFlags(value)
365+
}
366+
set(value) {
367+
setPref(LIBRARY_FILTER, AppFilter.toFlags(value))
368+
}
369+
359370
private val PERSONA_STATE = intPreferencesKey("persona_state")
360371
var personaState: EPersonaState
361372
get() {

app/src/main/java/com/OxGames/Pluvia/db/dao/SteamAppDao.kt

+5-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ interface SteamAppDao {
3131
invalidPkgId: Int = INVALID_PKG_ID,
3232
): Flow<List<SteamApp>>
3333

34-
@Query("SELECT * FROM steam_app WHERE received_pics = 0")
35-
fun getAllAppsWithoutPICS(): Flow<List<SteamApp>>
34+
@Query("SELECT * FROM steam_app WHERE received_pics = 0 AND package_id != :invalidPkgId AND owner_account_id = :ownerId")
35+
fun getAllOwnedAppsWithoutPICS(
36+
ownerId: Int,
37+
invalidPkgId: Int = INVALID_PKG_ID,
38+
): Flow<List<SteamApp>>
3639

3740
@Query("SELECT * FROM steam_app WHERE id = :appId")
3841
fun findApp(appId: Int): Flow<SteamApp?>

app/src/main/java/com/OxGames/Pluvia/enums/AppType.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ enum class AppType(val code: Int) {
6767
}
6868

6969
fun toFlags(value: EnumSet<AppType>): Int {
70-
return value.map { it.code }.reduce { first, second -> first or second }
70+
return value.map { it.code }.reduceOrNull { first, second -> first or second } ?: invalid.code
7171
}
7272

7373
fun fromCode(code: Int): AppType {

app/src/main/java/com/OxGames/Pluvia/enums/OS.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ enum class OS(val code: Int) {
3838
}
3939

4040
fun code(value: EnumSet<OS>): Int {
41-
return value.map { it.code }.reduce { first, second -> first or second }
41+
return value.map { it.code }.reduceOrNull { first, second -> first or second } ?: none.code
4242
}
4343
}
4444
}

app/src/main/java/com/OxGames/Pluvia/service/SteamService.kt

+26-9
Original file line numberDiff line numberDiff line change
@@ -1399,12 +1399,22 @@ class SteamService : Service(), IChallengeUrlChanged {
13991399
// Timber.d("Adding ${appToAdd?.name} with appId of ${appToAdd?.id} and pkgId of ${appToAdd?.packageId}")
14001400

14011401
val appIds = picsChangesCallback.appChanges.values
1402-
.filter { it.changeNumber != appDao.findApp(it.id).first()?.lastChangeNumber }
1402+
.filter { changeData ->
1403+
// only queue PICS requests for apps existing in the db that have changed
1404+
appDao.findApp(changeData.id).first()?.let {
1405+
changeData.changeNumber != it.lastChangeNumber
1406+
} == true
1407+
}
14031408
.map { AppRequest(it.id) }.toTypedArray()
14041409
queueAppPICSRequests(*appIds)
14051410

14061411
val pkgsWithChanges = picsChangesCallback.packageChanges.values
1407-
.filter { it.changeNumber != licenseDao.findLicense(it.id).first()?.lastChangeNumber }
1412+
.filter { changeData ->
1413+
// only queue PICS requests for pkgs existing in the db that have changed
1414+
licenseDao.findLicense(changeData.id).first()?.let {
1415+
changeData.changeNumber != it.lastChangeNumber
1416+
} == true
1417+
}
14081418
val pkgsForAccessTokens = pkgsWithChanges.filter { it.isNeedsToken }.map { it.id }
14091419
val accessTokens = _steamApps?.picsGetAccessTokens(
14101420
emptyList(),
@@ -1624,7 +1634,10 @@ class SteamService : Service(), IChallengeUrlChanged {
16241634
if (callback.result == EResult.OK) {
16251635
dbScope.launch {
16261636
// check first if any apps already exist in the db that need PICS
1627-
val apps = appDao.getAllAppsWithoutPICS().firstOrNull()?.map { AppRequest(it.id) }?.toTypedArray()
1637+
val apps = appDao.getAllOwnedAppsWithoutPICS(userSteamId!!.accountID.toInt())
1638+
.firstOrNull()
1639+
?.map { AppRequest(it.id) }
1640+
?.toTypedArray()
16281641
Timber.d("${apps?.size ?: 0} app(s) need PICS")
16291642
if (apps?.isNotEmpty() == true) {
16301643
queueAppPICSRequests(*apps)
@@ -1698,13 +1711,17 @@ class SteamService : Service(), IChallengeUrlChanged {
16981711
licenseDao.updateApps(pkg.id, appIds)
16991712
licenseDao.updateDepots(pkg.id, depotIds)
17001713

1701-
val steamAppsToAdd = appIds.map { appId ->
1702-
appDao.findApp(appId).first()?.copy(packageId = pkg.id)
1703-
?: SteamApp(id = appId, packageId = pkg.id)
1704-
}.toTypedArray()
1705-
appDao.insert(*steamAppsToAdd)
1714+
val license = licenseDao.findLicense(pkg.id).first()
1715+
// only add the apps belonging to the license if the user owns it
1716+
if (license?.ownerAccountId == userSteamId?.accountID?.toInt()) {
1717+
val steamAppsToAdd = appIds.map { appId ->
1718+
appDao.findApp(appId).first()?.copy(packageId = pkg.id)
1719+
?: SteamApp(id = appId, packageId = pkg.id)
1720+
}.toTypedArray()
17061721

1707-
queueAppPICSRequests(*appIds.map { AppRequest(it) }.toTypedArray())
1722+
appDao.insert(*steamAppsToAdd)
1723+
queueAppPICSRequests(*appIds.map { AppRequest(it) }.toTypedArray())
1724+
}
17081725
}
17091726
}
17101727

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.OxGames.Pluvia.ui.component
2+
3+
import androidx.compose.foundation.layout.padding
4+
import androidx.compose.material3.FilterChip
5+
import androidx.compose.runtime.Composable
6+
import androidx.compose.ui.Modifier
7+
import androidx.compose.ui.unit.dp
8+
9+
@Composable
10+
fun FlowFilterChip(
11+
selected: Boolean,
12+
onClick: () -> Unit,
13+
label: @Composable (() -> Unit),
14+
modifier: Modifier = Modifier,
15+
leadingIcon: @Composable (() -> Unit),
16+
) {
17+
FilterChip(
18+
modifier = Modifier.padding(end = 8.dp).then(modifier),
19+
onClick = onClick,
20+
label = label,
21+
selected = selected,
22+
leadingIcon = leadingIcon,
23+
)
24+
}

app/src/main/java/com/OxGames/Pluvia/ui/data/LibraryState.kt

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package com.OxGames.Pluvia.ui.data
22

3+
import com.OxGames.Pluvia.PrefManager
34
import com.OxGames.Pluvia.data.LibraryItem
4-
import com.OxGames.Pluvia.ui.enums.FabFilter
5+
import com.OxGames.Pluvia.ui.enums.AppFilter
56
import java.util.EnumSet
67

78
data class LibraryState(
8-
val appInfoSortType: EnumSet<FabFilter> = EnumSet.of(FabFilter.ALPHABETIC, FabFilter.GAME),
9+
val appInfoSortType: EnumSet<AppFilter> = PrefManager.libraryFilter,
910
val appInfoList: List<LibraryItem> = emptyList(),
11+
val modalBottomSheet: Boolean = false,
1012

1113
val isSearching: Boolean = false,
1214
val searchQuery: String = "",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.OxGames.Pluvia.ui.enums
2+
3+
import androidx.compose.material.icons.Icons
4+
import androidx.compose.material.icons.filled.AvTimer
5+
import androidx.compose.material.icons.filled.Build
6+
import androidx.compose.material.icons.filled.Computer
7+
import androidx.compose.material.icons.filled.InstallMobile
8+
import androidx.compose.material.icons.filled.VideogameAsset
9+
import androidx.compose.ui.graphics.vector.ImageVector
10+
import com.OxGames.Pluvia.enums.AppType
11+
import java.util.EnumSet
12+
13+
enum class AppFilter(
14+
val code: Int,
15+
val displayText: String,
16+
val icon: ImageVector,
17+
) {
18+
INSTALLED(
19+
code = 0x01,
20+
displayText = "Installed",
21+
icon = Icons.Default.InstallMobile,
22+
),
23+
GAME(
24+
code = 0x02,
25+
displayText = "Game",
26+
icon = Icons.Default.VideogameAsset,
27+
),
28+
APPLICATION(
29+
code = 0x04,
30+
displayText = "Application",
31+
icon = Icons.Default.Computer,
32+
),
33+
TOOL(
34+
code = 0x08,
35+
displayText = "Tool",
36+
icon = Icons.Default.Build,
37+
),
38+
DEMO(
39+
code = 0x10,
40+
displayText = "Demo",
41+
icon = Icons.Default.AvTimer,
42+
),
43+
// ALPHABETIC(
44+
// code = 0x20,
45+
// displayText = "Alphabetic",
46+
// icon = Icons.Default.SortByAlpha,
47+
// ),
48+
;
49+
50+
companion object {
51+
fun getAppType(appFilter: EnumSet<AppFilter>): EnumSet<AppType> {
52+
val output: EnumSet<AppType> = EnumSet.noneOf(AppType::class.java)
53+
if (appFilter.contains(GAME)) {
54+
output.add(AppType.game)
55+
}
56+
if (appFilter.contains(APPLICATION)) {
57+
output.add(AppType.application)
58+
}
59+
if (appFilter.contains(TOOL)) {
60+
output.add(AppType.tool)
61+
}
62+
if (appFilter.contains(DEMO)) {
63+
output.add(AppType.demo)
64+
}
65+
return output
66+
}
67+
68+
fun fromFlags(flags: Int): EnumSet<AppFilter> {
69+
val result = EnumSet.noneOf(AppFilter::class.java)
70+
AppFilter.entries.forEach { appFilter ->
71+
if (flags and appFilter.code == appFilter.code) {
72+
result.add(appFilter)
73+
}
74+
}
75+
return result
76+
}
77+
78+
fun toFlags(value: EnumSet<AppFilter>): Int {
79+
return value.map { it.code }.reduceOrNull { first, second -> first or second } ?: 0
80+
}
81+
}
82+
}

app/src/main/java/com/OxGames/Pluvia/ui/enums/FabFilter.kt

-33
This file was deleted.

app/src/main/java/com/OxGames/Pluvia/ui/model/LibraryViewModel.kt

+15-5
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import androidx.compose.runtime.mutableStateOf
66
import androidx.compose.runtime.setValue
77
import androidx.lifecycle.ViewModel
88
import androidx.lifecycle.viewModelScope
9+
import com.OxGames.Pluvia.PrefManager
910
import com.OxGames.Pluvia.data.LibraryItem
1011
import com.OxGames.Pluvia.data.SteamApp
1112
import com.OxGames.Pluvia.db.dao.SteamAppDao
1213
import com.OxGames.Pluvia.service.SteamService
1314
import com.OxGames.Pluvia.ui.data.LibraryState
14-
import com.OxGames.Pluvia.ui.enums.FabFilter
15+
import com.OxGames.Pluvia.ui.enums.AppFilter
1516
import dagger.hilt.android.lifecycle.HiltViewModel
17+
import java.util.EnumSet
1618
import javax.inject.Inject
1719
import kotlinx.coroutines.Dispatchers
1820
import kotlinx.coroutines.flow.MutableStateFlow
@@ -53,6 +55,10 @@ class LibraryViewModel @Inject constructor(
5355
}
5456
}
5557

58+
fun onModalBottomSheet(value: Boolean) {
59+
_state.update { it.copy(modalBottomSheet = value) }
60+
}
61+
5662
fun onIsSearching(value: Boolean) {
5763
_state.update { it.copy(isSearching = value) }
5864
if (!value) {
@@ -66,14 +72,18 @@ class LibraryViewModel @Inject constructor(
6672
}
6773

6874
// TODO: include other sort types
69-
fun onFabFilter(value: FabFilter) {
75+
fun onFilterChanged(value: AppFilter) {
7076
_state.update { currentState ->
71-
val updatedFilter = currentState.appInfoSortType
77+
val updatedFilter = EnumSet.copyOf(currentState.appInfoSortType)
78+
7279
if (updatedFilter.contains(value)) {
7380
updatedFilter.remove(value)
7481
} else {
7582
updatedFilter.add(value)
7683
}
84+
85+
PrefManager.libraryFilter = updatedFilter
86+
7787
currentState.copy(appInfoSortType = updatedFilter)
7888
}
7989

@@ -84,7 +94,7 @@ class LibraryViewModel @Inject constructor(
8494
Timber.d("onFilterApps")
8595
viewModelScope.launch {
8696
val currentState = _state.value
87-
val currentFilter = FabFilter.getAppType(currentState.appInfoSortType)
97+
val currentFilter = AppFilter.getAppType(currentState.appInfoSortType)
8898

8999
val filteredList = appList
90100
.asSequence()
@@ -99,7 +109,7 @@ class LibraryViewModel @Inject constructor(
99109
}
100110
}
101111
.filter { item ->
102-
if (currentState.appInfoSortType.contains(FabFilter.INSTALLED)) {
112+
if (currentState.appInfoSortType.contains(AppFilter.INSTALLED)) {
103113
SteamService.isAppInstalled(item.id)
104114
} else {
105115
true

0 commit comments

Comments
 (0)