commit 7938871086d68501335c86aec1baf4d7e3663e32
parent bbcaab4e75b4aac792907802532aacdb4a188cf4
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date: Sun, 29 Oct 2023 03:06:11 +0100
fix(app/tasks): download progress
- fix crashes
Diffstat:
4 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/download/DownloadProcessor.kt b/app/src/main/kotlin/me/rhunk/snapenhance/download/DownloadProcessor.kt
@@ -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())
}
}
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/task/PendingTask.kt b/app/src/main/kotlin/me/rhunk/snapenhance/task/PendingTask.kt
@@ -61,6 +61,7 @@ data class Task(
}
class PendingTask(
+ val taskId: Long,
val task: Task
) {
private val listeners = mutableListOf<PendingTaskListener>()
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/task/TaskManager.kt b/app/src/main/kotlin/me/rhunk/snapenhance/task/TaskManager.kt
@@ -89,7 +89,7 @@ class TaskManager(
updateTask(taskId, task)
}
- val pendingTask = PendingTask(task)
+ val pendingTask = PendingTask(taskId, task)
activeTasks[taskId] = pendingTask
return pendingTask
}
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/TasksSection.kt b/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/TasksSection.kt
@@ -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 {