Add download progress
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package io.nekohasekai.sfa.vendor
|
||||
|
||||
import io.nekohasekai.libbox.HTTPResponseWriteToProgressHandler
|
||||
import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.sfa.Application
|
||||
import io.nekohasekai.sfa.update.UpdateState
|
||||
@@ -27,7 +28,15 @@ class ApkDownloader : Closeable {
|
||||
request.setURL(url)
|
||||
|
||||
val response = request.execute()
|
||||
response.writeTo(apkFile.absolutePath)
|
||||
response.writeToWithProgress(
|
||||
apkFile.absolutePath,
|
||||
object : HTTPResponseWriteToProgressHandler {
|
||||
override fun update(progress: Long, total: Long) {
|
||||
UpdateState.downloadProgress.value =
|
||||
if (total > 0) progress.toFloat() / total.toFloat() else null
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
if (!apkFile.exists() || apkFile.length() == 0L) {
|
||||
throw Exception("Download failed: empty file")
|
||||
|
||||
@@ -42,6 +42,7 @@ import androidx.compose.material3.ExtendedFloatingActionButton
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.NavigationBar
|
||||
@@ -565,10 +566,22 @@ class MainActivity :
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
} else {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
CircularProgressIndicator(modifier = Modifier.size(24.dp))
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
Text(stringResource(R.string.downloading))
|
||||
val progress by UpdateState.downloadProgress
|
||||
Column {
|
||||
if (progress != null) {
|
||||
Text("${stringResource(R.string.downloading)} ${(progress!! * 100).toInt()}%")
|
||||
} else {
|
||||
Text(stringResource(R.string.downloading))
|
||||
}
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
if (progress != null) {
|
||||
LinearProgressIndicator(
|
||||
progress = { progress!! },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
} else {
|
||||
LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -580,6 +593,7 @@ class MainActivity :
|
||||
downloadJob = null
|
||||
showDownloadDialog = false
|
||||
downloadError = null
|
||||
UpdateState.downloadProgress.value = null
|
||||
},
|
||||
) {
|
||||
Text(stringResource(if (downloadError != null) R.string.ok else android.R.string.cancel))
|
||||
|
||||
@@ -47,6 +47,7 @@ import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.ListItemDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
@@ -261,10 +262,22 @@ fun AppSettingsScreen(navController: NavController) {
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
} else {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
CircularProgressIndicator(modifier = Modifier.size(24.dp))
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
Text(stringResource(R.string.downloading))
|
||||
val progress by UpdateState.downloadProgress
|
||||
Column {
|
||||
if (progress != null) {
|
||||
Text("${stringResource(R.string.downloading)} ${(progress!! * 100).toInt()}%")
|
||||
} else {
|
||||
Text(stringResource(R.string.downloading))
|
||||
}
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
if (progress != null) {
|
||||
LinearProgressIndicator(
|
||||
progress = { progress!! },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
} else {
|
||||
LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,6 +289,7 @@ fun AppSettingsScreen(navController: NavController) {
|
||||
downloadJob = null
|
||||
showDownloadDialog = false
|
||||
downloadError = null
|
||||
UpdateState.downloadProgress.value = null
|
||||
},
|
||||
) {
|
||||
Text(stringResource(if (downloadError != null) R.string.ok else android.R.string.cancel))
|
||||
|
||||
@@ -11,6 +11,7 @@ object UpdateState {
|
||||
val isChecking = mutableStateOf(false)
|
||||
|
||||
val isDownloading = mutableStateOf(false)
|
||||
val downloadProgress = mutableStateOf<Float?>(null)
|
||||
val downloadError = mutableStateOf<String?>(null)
|
||||
|
||||
val cachedApkFile = mutableStateOf<File?>(null)
|
||||
@@ -38,6 +39,7 @@ object UpdateState {
|
||||
hasUpdate.value = false
|
||||
updateInfo.value = null
|
||||
isDownloading.value = false
|
||||
downloadProgress.value = null
|
||||
downloadError.value = null
|
||||
installStatus.value = InstallStatus.Idle
|
||||
cachedApkFile.value = null
|
||||
@@ -46,6 +48,7 @@ object UpdateState {
|
||||
|
||||
fun resetDownload() {
|
||||
isDownloading.value = false
|
||||
downloadProgress.value = null
|
||||
downloadError.value = null
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user