fix(app/tasks): download progress

- fix crashes
This commit is contained in:
rhunk
2023-10-29 03:06:11 +01:00
parent bbcaab4e75
commit 7938871086
4 changed files with 28 additions and 21 deletions

View File

@@ -180,12 +180,14 @@ class DownloadProcessor (
private fun downloadInputMedias(pendingTask: PendingTask, downloadRequest: DownloadRequest) = runBlocking {
val jobs = mutableListOf<Job>()
val downloadedMedias = mutableMapOf<InputMedia, File>()
var totalSize = 1L
val inputMediaDownloadedBytes = mutableMapOf<InputMedia, Long>()
val inputMediaProgress = ConcurrentHashMap<InputMedia, String>()
fun updateDownloadProgress() {
pendingTask.updateProgress(
inputMediaProgress.values.joinToString("\n"),
progress = (jobs.filter { it.isActive }.size.toDouble() / jobs.size.toDouble() * 100.0).toInt()
progress = (inputMediaDownloadedBytes.values.sum() * 100 / totalSize).toInt().coerceIn(0, 100)
)
}
@@ -207,6 +209,7 @@ class DownloadProcessor (
while (decryptedInputStream.read(buffer).also { read = it } != -1) {
outputStream.write(buffer, 0, read)
totalRead += read
inputMediaDownloadedBytes[inputMedia] = totalRead
if (totalRead - lastTotalRead > 1024 * 1024) {
setProgress("${totalRead / 1024}KB/${estimatedSize / 1024}KB")
lastTotalRead = totalRead
@@ -219,6 +222,7 @@ class DownloadProcessor (
when (inputMedia.type) {
DownloadMediaType.PROTO_MEDIA -> {
RemoteMediaResolver.downloadBoltMedia(Base64.UrlSafe.decode(inputMedia.content), decryptionCallback = { it }, resultCallback = { inputStream, length ->
totalSize += length
handleInputStream(inputStream, estimatedSize = length)
})
}
@@ -227,6 +231,7 @@ class DownloadProcessor (
requestMethod = "GET"
setRequestProperty("User-Agent", Constants.USER_AGENT)
connect()
totalSize += contentLength.toLong()
handleInputStream(inputStream, estimatedSize = contentLength.toLong())
}
}

View File

@@ -61,6 +61,7 @@ data class Task(
}
class PendingTask(
val taskId: Long,
val task: Task
) {
private val listeners = mutableListOf<PendingTaskListener>()

View File

@@ -89,7 +89,7 @@ class TaskManager(
updateTask(taskId, task)
}
val pendingTask = PendingTask(task)
val pendingTask = PendingTask(taskId, task)
activeTasks[taskId] = pendingTask
return pendingTask
}

View File

@@ -25,7 +25,7 @@ import me.rhunk.snapenhance.ui.manager.Section
import me.rhunk.snapenhance.ui.util.OnLifecycleEvent
class TasksSection : Section() {
private lateinit var activeTasks: MutableMap<Long, PendingTask>
private var activeTasks by mutableStateOf(listOf<PendingTask>())
private lateinit var recentTasks: MutableList<Task>
@Composable
@@ -48,14 +48,14 @@ class TasksSection : Section() {
onClick = {
context.taskManager.clearAllTasks()
recentTasks.clear()
activeTasks.toList().forEach {
activeTasks.forEach {
runCatching {
it.second.cancel()
it.cancel()
}.onFailure { throwable ->
context.log.error("Failed to cancel task ${it.first}", throwable)
context.log.error("Failed to cancel task $it", throwable)
}
activeTasks.remove(it.first)
}
activeTasks = listOf()
context.taskManager.getActiveTasks().clear()
showConfirmDialog = false
}
@@ -90,7 +90,11 @@ class TasksSection : Section() {
taskProgressLabel = label
taskProgress = progress
}
).also { pendingTask?.addListener(it) }}
) }
LaunchedEffect(Unit) {
pendingTask?.addListener(listener)
}
DisposableEffect(Unit) {
onDispose {
@@ -163,7 +167,6 @@ class TasksSection : Section() {
override fun Content() {
val scrollState = rememberLazyListState()
val scope = rememberCoroutineScope()
activeTasks = remember { mutableStateMapOf() }
recentTasks = remember { mutableStateListOf() }
var lastFetchedTaskId: Long? by remember { mutableStateOf(null) }
@@ -172,28 +175,27 @@ class TasksSection : Section() {
val tasks = context.taskManager.fetchStoredTasks(lastFetchedTaskId ?: Long.MAX_VALUE)
if (tasks.isNotEmpty()) {
lastFetchedTaskId = tasks.keys.last()
recentTasks.addAll(tasks.filter { !activeTasks.containsKey(it.key) }.values)
scope.launch {
val activeTaskIds = activeTasks.map { it.taskId }
recentTasks.addAll(tasks.filter { it.key !in activeTaskIds }.values)
}
}
}
}
fun fetchActiveTasks() {
scope.launch {
activeTasks.clear()
activeTasks.putAll(context.taskManager.getActiveTasks())
}
activeTasks = context.taskManager.getActiveTasks().values.sortedByDescending { it.taskId }.toMutableList()
}
SideEffect {
LaunchedEffect(Unit) {
fetchActiveTasks()
}
OnLifecycleEvent { _, event ->
when (event) {
Lifecycle.Event.ON_RESUME -> {
if (event == Lifecycle.Event.ON_RESUME) {
scope.launch {
fetchActiveTasks()
}
else -> {}
}
}
@@ -213,11 +215,10 @@ class TasksSection : Section() {
}
}
}
items(activeTasks.size) { index ->
val pendingTask = activeTasks.values.elementAt(index)
items(activeTasks, key = { it.task.hash }) {pendingTask ->
TaskCard(modifier = Modifier.padding(8.dp), pendingTask.task, pendingTask = pendingTask)
}
items(recentTasks) { task ->
items(recentTasks, key = { it.hash }) { task ->
TaskCard(modifier = Modifier.padding(8.dp), task)
}
item {