Skip to content

Commit ce0856a

Browse files
committed
Add loading animation during import
1 parent df181a6 commit ce0856a

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

app/src/main/java/dev/zwander/installwithoptions/MainActivity.kt

+45-5
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import androidx.compose.runtime.collectAsState
6161
import androidx.compose.runtime.getValue
6262
import androidx.compose.runtime.mutableStateOf
6363
import androidx.compose.runtime.remember
64+
import androidx.compose.runtime.rememberCoroutineScope
6465
import androidx.compose.runtime.setValue
6566
import androidx.compose.ui.Alignment
6667
import androidx.compose.ui.Modifier
@@ -85,8 +86,12 @@ import dev.zwander.installwithoptions.util.ElevatedPermissionHandler
8586
import dev.zwander.installwithoptions.util.handleIncomingUris
8687
import dev.zwander.installwithoptions.util.plus
8788
import dev.zwander.installwithoptions.util.rememberPackageInstaller
89+
import kotlinx.coroutines.CoroutineScope
90+
import kotlinx.coroutines.Dispatchers
91+
import kotlinx.coroutines.MainScope
92+
import kotlinx.coroutines.launch
8893

89-
class MainActivity : AppCompatActivity() {
94+
class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
9095
private val permissionHandler by lazy {
9196
ElevatedPermissionHandler(
9297
context = this,
@@ -132,24 +137,31 @@ class MainActivity : AppCompatActivity() {
132137

133138
private fun checkIntentForPackage(intent: Intent) {
134139
intent.data?.let {
135-
handleIncomingUris(listOf(it))
140+
launch(Dispatchers.IO) {
141+
handleIncomingUris(listOf(it))
142+
}
136143
}
137144
}
138145
}
139146

140147
@OptIn(ExperimentalFoundationApi::class)
141148
@Composable
142149
fun MainContent(modifier: Modifier = Modifier) {
150+
val scope = rememberCoroutineScope()
151+
143152
var selectedFiles by DataModel.selectedFiles.collectAsMutableState()
144153
var showingSelectedFiles by remember {
145154
mutableStateOf(false)
146155
}
147156
var selectedOptions by DataModel.selectedOptions.collectAsMutableState()
157+
val isImporting by DataModel.isImporting.collectAsState()
148158

149159
val context = LocalContext.current
150160
val fileSelector =
151161
rememberLauncherForActivityResult(contract = ActivityResultContracts.OpenMultipleDocuments()) { uris ->
152-
context.handleIncomingUris(uris)
162+
scope.launch(Dispatchers.IO) {
163+
context.handleIncomingUris(uris)
164+
}
153165
}
154166
val options = (rememberInstallOptions() + rememberMutableOptions()).sortedBy {
155167
context.resources.getString(it.labelResource)
@@ -324,6 +336,32 @@ fun MainContent(modifier: Modifier = Modifier) {
324336
}
325337
}
326338
}
339+
340+
AnimatedVisibility(
341+
visible = isImporting,
342+
modifier = Modifier.fillMaxSize(),
343+
enter = fadeIn(),
344+
exit = fadeOut(),
345+
) {
346+
Box(
347+
modifier = Modifier
348+
.fillMaxSize()
349+
.background(Color.Black.copy(alpha = 0.5f))
350+
.clickable(
351+
interactionSource = remember {
352+
MutableInteractionSource()
353+
},
354+
indication = null,
355+
enabled = true,
356+
onClick = {},
357+
),
358+
contentAlignment = Alignment.Center,
359+
) {
360+
CircularProgressIndicator(
361+
color = Color.White,
362+
)
363+
}
364+
}
327365
}
328366

329367
if (showingSelectedFiles) {
@@ -344,7 +382,8 @@ fun MainContent(modifier: Modifier = Modifier) {
344382
selectedFiles.forEach { (pkg, files) ->
345383
stickyHeader {
346384
Row(
347-
modifier = Modifier.fillMaxWidth()
385+
modifier = Modifier
386+
.fillMaxWidth()
348387
.background(color = MaterialTheme.colorScheme.surfaceContainerHigh),
349388
horizontalArrangement = Arrangement.SpaceBetween,
350389
verticalAlignment = Alignment.CenterVertically,
@@ -370,7 +409,8 @@ fun MainContent(modifier: Modifier = Modifier) {
370409

371410
items(items = files) {
372411
Row(
373-
modifier = Modifier.fillMaxWidth()
412+
modifier = Modifier
413+
.fillMaxWidth()
374414
.background(color = MaterialTheme.colorScheme.surfaceContainerHigh),
375415
horizontalArrangement = Arrangement.SpaceBetween,
376416
verticalAlignment = Alignment.CenterVertically,

app/src/main/java/dev/zwander/installwithoptions/data/DataModel.kt

+1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ object DataModel {
88
val rootGranted = MutableStateFlow(false)
99
val selectedOptions = Settings.Keys.selectedOptions.asMutableStateFlow()
1010
val selectedFiles = MutableStateFlow(mapOf<String, List<DocumentFile>>())
11+
val isImporting = MutableStateFlow(false)
1112
}

app/src/main/java/dev/zwander/installwithoptions/util/IncomingPackageUtils.kt

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import net.lingala.zip4j.ZipFile
1111
import java.io.File
1212

1313
fun Context.handleIncomingUris(uris: List<Uri>) {
14+
DataModel.isImporting.value = true
1415
val currentSelection = DataModel.selectedFiles.value.toMutableMap()
1516

1617
fun addApkFile(file: DocumentFile) {
@@ -36,6 +37,7 @@ fun Context.handleIncomingUris(uris: List<Uri>) {
3637
}
3738

3839
DataModel.selectedFiles.value = currentSelection
40+
DataModel.isImporting.value = false
3941
}
4042

4143
private fun Context.copyZipToCacheAndExtract(zip: DocumentFile): List<DocumentFile> {

0 commit comments

Comments
 (0)