@@ -3,6 +3,7 @@ package neth.iecal.trease.ui.dialogs
33import android.graphics.drawable.Drawable
44import androidx.compose.foundation.Image
55import androidx.compose.foundation.clickable
6+ import androidx.compose.foundation.layout.Box
67import androidx.compose.foundation.layout.Column
78import androidx.compose.foundation.layout.Row
89import androidx.compose.foundation.layout.Spacer
@@ -18,6 +19,7 @@ import androidx.compose.material.icons.filled.Search
1819import androidx.compose.material3.AlertDialog
1920import androidx.compose.material3.Button
2021import androidx.compose.material3.Checkbox
22+ import androidx.compose.material3.CircularProgressIndicator
2123import androidx.compose.material3.Icon
2224import androidx.compose.material3.IconButton
2325import androidx.compose.material3.MaterialTheme
@@ -56,6 +58,7 @@ fun AppSelectionDialog(
5658 var installedApps by remember { mutableStateOf(listOf<AppInfo >()) }
5759 var searchQuery by remember { mutableStateOf(" " ) }
5860
61+ var isLoading by remember {mutableStateOf(true )}
5962 val filteredApps by remember(searchQuery, installedApps) {
6063 derivedStateOf {
6164 if (searchQuery.isBlank()) {
@@ -97,6 +100,7 @@ fun AppSelectionDialog(
97100 }
98101 }
99102 icons = tempMap
103+ isLoading = false
100104 }
101105
102106 AlertDialog (
@@ -128,73 +132,78 @@ fun AppSelectionDialog(
128132 .fillMaxWidth()
129133 .padding(bottom = 16 .dp)
130134 )
131- Text (
132- text = " Note that all the selected apps will be immediately killed. Please save all unsaved files before starting the app blocker." ,
133- style = MaterialTheme .typography.bodyMedium,
134- color = MaterialTheme .colorScheme.error,
135- modifier = Modifier .padding(vertical = 8 .dp, horizontal = 4 .dp)
136- )
137135
138- LazyColumn (
139- modifier = Modifier .heightIn(max = 400 .dp)
140- ) {
141- items(filteredApps, key = { it.packageName }) { app ->
142- val isSelected = currentSelection.contains(app.packageName)
136+ if (isLoading) {
137+ Box (
138+ modifier = Modifier
139+ .fillMaxWidth()
140+ .heightIn(min = 200 .dp),
141+ contentAlignment = Alignment .Center
142+ ) {
143+ CircularProgressIndicator ()
144+ }
145+ } else {
146+ LazyColumn (
147+ modifier = Modifier .heightIn(max = 400 .dp)
148+ ) {
149+ items(filteredApps, key = { it.packageName }) { app ->
150+ val isSelected = currentSelection.contains(app.packageName)
143151
144- Row (
145- verticalAlignment = Alignment .CenterVertically ,
146- modifier = Modifier
147- .fillMaxWidth()
148- .clip(MaterialTheme .shapes.small)
149- .clickable {
150- currentSelection = if (isSelected) {
151- currentSelection - app.packageName
152- } else {
153- currentSelection + app.packageName
152+ Row (
153+ verticalAlignment = Alignment .CenterVertically ,
154+ modifier = Modifier
155+ .fillMaxWidth()
156+ .clip(MaterialTheme .shapes.small)
157+ .clickable {
158+ currentSelection = if (isSelected) {
159+ currentSelection - app.packageName
160+ } else {
161+ currentSelection + app.packageName
162+ }
154163 }
164+ .padding(vertical = 8 .dp, horizontal = 4 .dp)
165+ ) {
166+ Checkbox (
167+ checked = isSelected,
168+ onCheckedChange = null // Handled by Row clickable for better UX
169+ )
170+ Spacer (modifier = Modifier .padding(8 .dp))
171+ Image (
172+ painter = rememberAsyncImagePainter(icons[app.packageName]),
173+ contentDescription = " App Icon" ,
174+ modifier = Modifier .size(48 .dp)
175+ )
176+ Spacer (modifier = Modifier .padding(8 .dp))
177+ Column {
178+
179+ Text (
180+ text = app.name,
181+ style = MaterialTheme .typography.bodyLarge,
182+ maxLines = 1 ,
183+ overflow = TextOverflow .Ellipsis
184+ )
185+ Text (
186+ text = app.packageName,
187+ style = MaterialTheme .typography.bodySmall,
188+ color = MaterialTheme .colorScheme.onSurfaceVariant,
189+ maxLines = 1 ,
190+ overflow = TextOverflow .Ellipsis
191+ )
155192 }
156- .padding(vertical = 8 .dp, horizontal = 4 .dp)
157- ) {
158- Checkbox (
159- checked = isSelected,
160- onCheckedChange = null // Handled by Row clickable for better UX
161- )
162- Spacer (modifier = Modifier .padding(8 .dp))
163- Image (
164- painter = rememberAsyncImagePainter(icons[app.packageName]),
165- contentDescription = " App Icon" ,
166- modifier = Modifier .size(48 .dp)
167- )
168- Spacer (modifier = Modifier .padding(8 .dp))
169- Column {
193+ }
194+ }
170195
196+ if (filteredApps.isEmpty()) {
197+ item {
171198 Text (
172- text = app.name,
173- style = MaterialTheme .typography.bodyLarge,
174- maxLines = 1 ,
175- overflow = TextOverflow .Ellipsis
176- )
177- Text (
178- text = app.packageName,
179- style = MaterialTheme .typography.bodySmall,
199+ text = " No apps found" ,
200+ style = MaterialTheme .typography.bodyMedium,
180201 color = MaterialTheme .colorScheme.onSurfaceVariant,
181- maxLines = 1 ,
182- overflow = TextOverflow .Ellipsis
202+ modifier = Modifier .padding(16 .dp)
183203 )
184204 }
185205 }
186206 }
187-
188- if (filteredApps.isEmpty()) {
189- item {
190- Text (
191- text = " No apps found" ,
192- style = MaterialTheme .typography.bodyMedium,
193- color = MaterialTheme .colorScheme.onSurfaceVariant,
194- modifier = Modifier .padding(16 .dp)
195- )
196- }
197- }
198207 }
199208 }
200209 },
0 commit comments