Skip to content

Commit 20e5153

Browse files
committed
Fix app list chips and filter behavior
1 parent e1b7111 commit 20e5153

1 file changed

Lines changed: 111 additions & 43 deletions

File tree

app/src/main/kotlin/com/dev/debloater/MainActivity.kt

Lines changed: 111 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import androidx.compose.animation.core.tween
2020
import androidx.compose.foundation.Image
2121
import androidx.compose.foundation.background
2222
import androidx.compose.foundation.clickable
23+
import androidx.compose.foundation.horizontalScroll
24+
import androidx.compose.foundation.rememberScrollState
2325
import androidx.compose.foundation.gestures.FlingBehavior
2426
import androidx.compose.foundation.gestures.ScrollableDefaults
2527
import androidx.compose.foundation.isSystemInDarkTheme
@@ -111,6 +113,13 @@ data class ConfirmAction(
111113
val appName: String
112114
)
113115

116+
data class AppFilters(
117+
val systemOnly: Boolean = false,
118+
val userOnly: Boolean = false,
119+
val disabledOnly: Boolean = false,
120+
val uninstalledOnly: Boolean = false,
121+
)
122+
114123
private fun SafetyLevel.badgeColorScheme(): Pair<Color, Color> =
115124
when (this) {
116125
SafetyLevel.SAFE -> Color(0xFF1B5E20) to Color(0xFFE8F5E9)
@@ -142,6 +151,7 @@ fun DebloaterScreen(snackbarHostState: SnackbarHostState) {
142151
var allAppData by remember { mutableStateOf<List<AppData>>(emptyList()) }
143152
var query by rememberSaveable { mutableStateOf("") }
144153
var active by rememberSaveable { mutableStateOf(false) }
154+
var filters by rememberSaveable { mutableStateOf(AppFilters()) }
145155
var isRefreshing by remember { mutableStateOf(false) }
146156
var confirmAction by remember { mutableStateOf<ConfirmAction?>(null) }
147157
var riskyOverrideAction by remember { mutableStateOf<ConfirmAction?>(null) }
@@ -189,10 +199,23 @@ fun DebloaterScreen(snackbarHostState: SnackbarHostState) {
189199

190200
val filteredAppData by remember {
191201
derivedStateOf {
192-
if (query.isBlank()) allAppData
193-
else allAppData.filter {
194-
it.appName.contains(query, ignoreCase = true) ||
195-
it.packageName.contains(query, ignoreCase = true)
202+
val trimmedQuery = query.trim()
203+
204+
allAppData.filter { appData ->
205+
val matchesQuery = trimmedQuery.isBlank() ||
206+
appData.appName.contains(trimmedQuery, ignoreCase = true) ||
207+
appData.packageName.contains(trimmedQuery, ignoreCase = true)
208+
209+
val matchesSystemUser = when {
210+
filters.systemOnly -> appData.isSystem
211+
filters.userOnly -> !appData.isSystem
212+
else -> true
213+
}
214+
215+
val matchesDisabled = !filters.disabledOnly || appData.isDisabled
216+
val matchesUninstalled = !filters.uninstalledOnly || !appData.isInstalled
217+
218+
matchesQuery && matchesSystemUser && matchesDisabled && matchesUninstalled
196219
}
197220
}
198221
}
@@ -212,6 +235,8 @@ fun DebloaterScreen(snackbarHostState: SnackbarHostState) {
212235
onActiveChange = { active = it },
213236
suggestions = filteredAppData.take(10),
214237
onSuggestionClick = { query = it; active = false },
238+
filters = filters,
239+
onFiltersChange = { filters = it },
215240
suggestionListState = suggestionListState,
216241
smoothFlingBehavior = smoothFlingBehavior,
217242
currentScreen = currentScreen,
@@ -633,6 +658,8 @@ fun DebloaterTopBar(
633658
onActiveChange: (Boolean) -> Unit,
634659
suggestions: List<AppData>,
635660
onSuggestionClick: (String) -> Unit,
661+
filters: AppFilters,
662+
onFiltersChange: (AppFilters) -> Unit,
636663
suggestionListState: LazyListState,
637664
smoothFlingBehavior: FlingBehavior,
638665
currentScreen: String,
@@ -669,50 +696,91 @@ fun DebloaterTopBar(
669696
)
670697

671698
if (currentScreen == "apps") {
672-
SearchBar(
673-
query = query,
674-
onQueryChange = onQueryChange,
675-
onSearch = { onActiveChange(false) },
676-
active = active,
677-
onActiveChange = onActiveChange,
678-
placeholder = { Text("Search apps") },
679-
leadingIcon = {
680-
if (active) {
681-
IconButton(onClick = {
682-
onQueryChange("")
683-
onActiveChange(false)
684-
}) {
685-
Icon(Icons.Default.ArrowBack, null)
699+
Column {
700+
SearchBar(
701+
query = query,
702+
onQueryChange = onQueryChange,
703+
onSearch = { onActiveChange(false) },
704+
active = active,
705+
onActiveChange = onActiveChange,
706+
placeholder = { Text("Search apps") },
707+
leadingIcon = {
708+
if (active) {
709+
IconButton(onClick = {
710+
onQueryChange("")
711+
onActiveChange(false)
712+
}) {
713+
Icon(Icons.Default.ArrowBack, null)
714+
}
715+
} else {
716+
Icon(Icons.Default.Search, null)
686717
}
687-
} else {
688-
Icon(Icons.Default.Search, null)
689-
}
690-
},
691-
trailingIcon = {
692-
if (query.isNotBlank()) {
693-
IconButton(onClick = { onQueryChange("") }) {
694-
Icon(Icons.Default.Close, null)
718+
},
719+
trailingIcon = {
720+
if (query.isNotBlank()) {
721+
IconButton(onClick = { onQueryChange("") }) {
722+
Icon(Icons.Default.Close, null)
723+
}
695724
}
696-
}
697-
},
698-
modifier = Modifier
699-
.fillMaxWidth()
700-
.padding(horizontal = 16.dp, vertical = 8.dp)
701-
) {
702-
LazyColumn(
703-
state = suggestionListState,
704-
flingBehavior = smoothFlingBehavior
725+
},
726+
modifier = Modifier
727+
.fillMaxWidth()
728+
.padding(horizontal = 16.dp, vertical = 8.dp)
705729
) {
706-
items(suggestions, key = { it.packageName }) { appData ->
707-
ListItem(
708-
headlineContent = { Text(appData.appName) },
709-
supportingContent = { Text(appData.packageName) },
710-
modifier = Modifier.clickable {
711-
onSuggestionClick(appData.appName)
712-
}
713-
)
730+
LazyColumn(
731+
state = suggestionListState,
732+
flingBehavior = smoothFlingBehavior
733+
) {
734+
items(suggestions, key = { it.packageName }) { appData ->
735+
ListItem(
736+
headlineContent = { Text(appData.appName) },
737+
supportingContent = { Text(appData.packageName) },
738+
modifier = Modifier.clickable {
739+
onSuggestionClick(appData.appName)
740+
}
741+
)
742+
}
714743
}
715744
}
745+
746+
Row(
747+
modifier = Modifier
748+
.fillMaxWidth()
749+
.horizontalScroll(rememberScrollState())
750+
.padding(horizontal = 16.dp, vertical = 4.dp),
751+
horizontalArrangement = Arrangement.spacedBy(8.dp)
752+
) {
753+
FilterChip(
754+
selected = filters.systemOnly,
755+
onClick = {
756+
val enabled = !filters.systemOnly
757+
onFiltersChange(filters.copy(systemOnly = enabled, userOnly = if (enabled) false else filters.userOnly))
758+
},
759+
label = { Text("System") }
760+
)
761+
FilterChip(
762+
selected = filters.userOnly,
763+
onClick = {
764+
val enabled = !filters.userOnly
765+
onFiltersChange(filters.copy(userOnly = enabled, systemOnly = if (enabled) false else filters.systemOnly))
766+
},
767+
label = { Text("User") }
768+
)
769+
FilterChip(
770+
selected = filters.disabledOnly,
771+
onClick = {
772+
onFiltersChange(filters.copy(disabledOnly = !filters.disabledOnly))
773+
},
774+
label = { Text("Disabled") }
775+
)
776+
FilterChip(
777+
selected = filters.uninstalledOnly,
778+
onClick = {
779+
onFiltersChange(filters.copy(uninstalledOnly = !filters.uninstalledOnly))
780+
},
781+
label = { Text("Uninstalled") }
782+
)
783+
}
716784
}
717785
}
718786
}

0 commit comments

Comments
 (0)