diff --git a/app/src/main/java/eu/kanade/data/TransactionContext.kt b/app/src/main/java/eu/kanade/data/TransactionContext.kt index 52794d539d..34990576ca 100644 --- a/app/src/main/java/eu/kanade/data/TransactionContext.kt +++ b/app/src/main/java/eu/kanade/data/TransactionContext.kt @@ -107,16 +107,16 @@ private suspend fun CoroutineDispatcher.acquireTransactionThread( try { dispatch(EmptyCoroutineContext) { runBlocking { - // Thread acquired, resume coroutine. + // Thread acquired, resume coroutine continuation.resume(coroutineContext[ContinuationInterceptor]!!) controlJob.join() } } } catch (ex: RejectedExecutionException) { - // Couldn't acquire a thread, cancel coroutine. + // Couldn't acquire a thread, cancel coroutine continuation.cancel( IllegalStateException( - "Unable to acquire a thread to perform the database transaction.", + "Unable to acquire a thread to perform the database transaction", ex, ), ) @@ -152,7 +152,7 @@ private class TransactionElement( fun release() { val count = referenceCount.decrementAndGet() if (count < 0) { - throw IllegalStateException("Transaction was never started or was already released.") + throw IllegalStateException("Transaction was never started or was already released") } else if (count == 0) { // Cancel the job that controls the transaction thread, causing it to be released. transactionThreadControlJob.cancel() diff --git a/app/src/main/java/eu/kanade/presentation/components/VerticalFastScroller.kt b/app/src/main/java/eu/kanade/presentation/components/VerticalFastScroller.kt index 05c3dc3a2b..c18049f6ac 100644 --- a/app/src/main/java/eu/kanade/presentation/components/VerticalFastScroller.kt +++ b/app/src/main/java/eu/kanade/presentation/components/VerticalFastScroller.kt @@ -196,7 +196,7 @@ private fun rememberColumnWidthSums( ) { { constraints -> require(constraints.maxWidth != Constraints.Infinity) { - "LazyVerticalGrid's width should be bound by parent." + "LazyVerticalGrid's width should be bound by parent" } val horizontalPadding = contentPadding.calculateStartPadding(LayoutDirection.Ltr) + contentPadding.calculateEndPadding(LayoutDirection.Ltr) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt index e0cf8f2e6b..01e59f8682 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt @@ -69,14 +69,14 @@ class BackupRestoreService : Service() { */ private lateinit var wakeLock: PowerManager.WakeLock - private lateinit var ioScope: CoroutineScope + private lateinit var scope: CoroutineScope private var restorer: BackupRestorer? = null private lateinit var notifier: BackupNotifier override fun onCreate() { super.onCreate() - ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) + scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) notifier = BackupNotifier(this) wakeLock = acquireWakeLock(javaClass.name) @@ -95,7 +95,7 @@ class BackupRestoreService : Service() { private fun destroyJob() { restorer?.job?.cancel() - ioScope.cancel() + scope.cancel() if (wakeLock.isHeld) { wakeLock.release() } @@ -129,7 +129,7 @@ class BackupRestoreService : Service() { notifier.showRestoreError(exception.message) stopSelf(startId) } - val job = ioScope.launch(handler) { + val job = scope.launch(handler) { if (restorer?.restoreBackup(uri) == false) { notifier.showRestoreError(getString(R.string.restoring_backup_canceled)) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt b/app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt index 160782bc1a..42ef7fe34f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt @@ -23,12 +23,12 @@ class TachiyomiImageDecoder(private val resources: ImageSource, private val opti ImageDecoder.newInstance(it.inputStream()) } - check(decoder != null && decoder.width > 0 && decoder.height > 0) { "Failed to initialize decoder." } + check(decoder != null && decoder.width > 0 && decoder.height > 0) { "Failed to initialize decoder" } val bitmap = decoder.decode(rgb565 = options.allowRgb565) decoder.recycle() - check(bitmap != null) { "Failed to decode image." } + check(bitmap != null) { "Failed to decode image" } return DecodeResult( drawable = bitmap.toDrawable(options.context.resources), diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt index f63d96f860..50f539caab 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt @@ -84,12 +84,22 @@ class DownloadManager( downloader.clearQueue(isNotification) } + /** + * Returns the download from queue if the chapter is queued for download + * else it will return null which means that the chapter is not queued for download + * + * @param chapterId the chapter to check. + */ + fun getQueuedDownloadOrNull(chapterId: Long): Download? { + return queue.find { it.chapter.id == chapterId } + } + fun startDownloadNow(chapterId: Long?) { if (chapterId == null) return - val download = downloader.queue.find { it.chapter.id == chapterId } + val download = getQueuedDownloadOrNull(chapterId) // If not in queue try to start a new download val toAdd = download ?: runBlocking { Download.fromChapterId(chapterId) } ?: return - val queue = downloader.queue.toMutableList() + val queue = queue.toMutableList() download?.let { queue.remove(it) } queue.add(0, toAdd) reorderQueue(queue) @@ -112,13 +122,13 @@ class DownloadManager( if (downloads.isEmpty()) { DownloadService.stop(context) - downloader.queue.clear() + queue.clear() return } downloader.pause() - downloader.queue.clear() - downloader.queue.addAll(downloads) + queue.clear() + queue.addAll(downloads) if (wasRunning) { downloader.start() @@ -194,17 +204,6 @@ class DownloadManager( return cache.isChapterDownloaded(chapterName, chapterScanlator, mangaTitle, sourceId, skipCache) } - /** - * Returns the download from queue if the chapter is queued for download - * else it will return null which means that the chapter is not queued for download - * - * @param chapter the chapter to check. - */ - fun getChapterDownloadOrNull(chapter: Chapter): Download? { - return downloader.queue - .firstOrNull { it.chapter.id == chapter.id && it.chapter.manga_id == chapter.mangaId } - } - /** * Returns the amount of downloaded chapters. */ @@ -221,9 +220,8 @@ class DownloadManager( return cache.getDownloadCount(manga) } - fun deletePendingDownloads(downloads: List) { - val domainChapters = downloads.map { it.chapter.toDomainChapter()!! } - removeFromDownloadQueue(domainChapters) + fun cancelQueuedDownloads(downloads: List) { + removeFromDownloadQueue(downloads.mapNotNull { it.chapter.toDomainChapter() }) } /** @@ -235,7 +233,6 @@ class DownloadManager( */ fun deleteChapters(chapters: List, manga: Manga, source: Source) { val filteredChapters = getChaptersToDelete(chapters, manga) - if (filteredChapters.isNotEmpty()) { launchIO { removeFromDownloadQueue(filteredChapters) @@ -260,7 +257,7 @@ class DownloadManager( */ fun deleteManga(manga: Manga, source: Source) { launchIO { - downloader.queue.remove(manga) + queue.remove(manga) provider.findMangaDir(manga.title, source)?.delete() cache.removeManga(manga) @@ -279,13 +276,13 @@ class DownloadManager( downloader.pause() } - downloader.queue.remove(chapters) + queue.remove(chapters) if (wasRunning) { - if (downloader.queue.isEmpty()) { + if (queue.isEmpty()) { DownloadService.stop(context) downloader.stop() - } else if (downloader.queue.isNotEmpty()) { + } else if (queue.isNotEmpty()) { downloader.start() } } @@ -297,7 +294,7 @@ class DownloadManager( * @param chapters the list of chapters to delete. * @param manga the manga of the chapters. */ - fun enqueueDeleteChapters(chapters: List, manga: Manga) { + fun enqueueChaptersToDelete(chapters: List, manga: Manga) { pendingDeleter.addChapters(getChaptersToDelete(chapters, manga), manga) } @@ -326,13 +323,13 @@ class DownloadManager( if (capitalizationChanged) { val tempName = newName + "_tmp" if (oldFolder.renameTo(tempName).not()) { - logcat(LogPriority.ERROR) { "Failed to rename source download folder: ${oldFolder.name}." } + logcat(LogPriority.ERROR) { "Failed to rename source download folder: ${oldFolder.name}" } return } } if (oldFolder.renameTo(newName).not()) { - logcat(LogPriority.ERROR) { "Failed to rename source download folder: ${oldFolder.name}." } + logcat(LogPriority.ERROR) { "Failed to rename source download folder: ${oldFolder.name}" } } } @@ -362,7 +359,7 @@ class DownloadManager( cache.removeChapter(oldChapter, manga) cache.addChapter(newName, mangaDir, manga) } else { - logcat(LogPriority.ERROR) { "Could not rename downloaded chapter: ${oldNames.joinToString()}." } + logcat(LogPriority.ERROR) { "Could not rename downloaded chapter: ${oldNames.joinToString()}" } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt index 6aac6c7892..62d90e7da4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt @@ -82,11 +82,11 @@ class DownloadService : Service() { */ private lateinit var wakeLock: PowerManager.WakeLock - private lateinit var ioScope: CoroutineScope + private lateinit var scope: CoroutineScope override fun onCreate() { super.onCreate() - ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) + scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) startForeground(Notifications.ID_DOWNLOAD_CHAPTER_PROGRESS, getPlaceholderNotification()) wakeLock = acquireWakeLock(javaClass.name) _isRunning.value = true @@ -95,7 +95,7 @@ class DownloadService : Service() { } override fun onDestroy() { - ioScope?.cancel() + scope?.cancel() _isRunning.value = false downloadManager.stopDownloads() wakeLock.releaseIfHeld() @@ -140,7 +140,7 @@ class DownloadService : Service() { stopSelf() } } - .launchIn(ioScope) + .launchIn(scope) } /** @@ -158,7 +158,7 @@ class DownloadService : Service() { .catch { // Ignore errors } - .launchIn(ioScope) + .launchIn(scope) } private fun PowerManager.WakeLock.releaseIfHeld() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt index ee843a0741..6c37379d73 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt @@ -100,7 +100,7 @@ class LibraryUpdateService( private lateinit var wakeLock: PowerManager.WakeLock private lateinit var notifier: LibraryUpdateNotifier - private var ioScope: CoroutineScope? = null + private var scope: CoroutineScope? = null private var mangaToUpdate: List = mutableListOf() private var updateJob: Job? = null @@ -188,7 +188,7 @@ class LibraryUpdateService( */ override fun onDestroy() { updateJob?.cancel() - ioScope?.cancel() + scope?.cancel() if (wakeLock.isHeld) { wakeLock.release() } @@ -220,7 +220,7 @@ class LibraryUpdateService( // Unsubscribe from any previous subscription if needed updateJob?.cancel() - ioScope?.cancel() + scope?.cancel() // If this is a chapter update; set the last update time to now if (target == Target.CHAPTERS) { @@ -236,8 +236,8 @@ class LibraryUpdateService( logcat(LogPriority.ERROR, exception) stopSelf(startId) } - ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) - updateJob = ioScope?.launch(handler) { + scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) + updateJob = scope?.launch(handler) { when (target) { Target.CHAPTERS -> updateChapterList() Target.COVERS -> updateCovers() diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/installer/ShizukuInstaller.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/installer/ShizukuInstaller.kt index 2c3f617e05..68311c1fbe 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/installer/ShizukuInstaller.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/installer/ShizukuInstaller.kt @@ -20,7 +20,7 @@ import java.io.InputStream class ShizukuInstaller(private val service: Service) : Installer(service) { - private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) + private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) private val shizukuDeadListener = Shizuku.OnBinderDeadListener { logcat { "Shizuku was killed prematurely" } @@ -46,7 +46,7 @@ class ShizukuInstaller(private val service: Service) : Installer(service) { @Suppress("BlockingMethodInNonBlockingContext") override fun processEntry(entry: Entry) { super.processEntry(entry) - ioScope.launch { + scope.launch { var sessionId: String? = null try { val size = service.getUriSize(entry.uri) ?: throw IllegalStateException() @@ -88,7 +88,7 @@ class ShizukuInstaller(private val service: Service) : Installer(service) { override fun onDestroy() { Shizuku.removeBinderDeadListener(shizukuDeadListener) Shizuku.removeRequestPermissionResultListener(shizukuPermissionListener) - ioScope.cancel() + scope.cancel() super.onDestroy() } @@ -116,7 +116,7 @@ class ShizukuInstaller(private val service: Service) : Installer(service) { false } } else { - logcat(LogPriority.ERROR) { "Shizuku is not ready to use." } + logcat(LogPriority.ERROR) { "Shizuku is not ready to use" } service.toast(R.string.ext_installer_shizuku_stopped) service.stopSelf() false diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt index d9ddce1900..cff0282fbf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt @@ -479,7 +479,7 @@ class DownloadController : presenter.reorder(selectedSeries + otherSeries) } R.id.cancel_download -> { - presenter.cancelDownloads(listOf(item.download)) + presenter.cancel(listOf(item.download)) } R.id.cancel_series -> { val allDownloadsForSeries = adapter?.currentItems @@ -487,7 +487,7 @@ class DownloadController : ?.filter { item.download.manga.id == it.download.manga.id } ?.map(DownloadItem::download) if (!allDownloadsForSeries.isNullOrEmpty()) { - presenter.cancelDownloads(allDownloadsForSeries) + presenter.cancel(allDownloadsForSeries) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.kt index 2f42538bdb..990b2fd23e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.kt @@ -5,7 +5,6 @@ import android.os.Bundle import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadService import eu.kanade.tachiyomi.data.download.model.Download -import eu.kanade.tachiyomi.data.download.model.DownloadQueue import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.util.system.logcat import kotlinx.coroutines.flow.MutableStateFlow @@ -15,17 +14,12 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import logcat.LogPriority -import uy.kohesive.injekt.injectLazy +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get -class DownloadPresenter : BasePresenter() { - - val downloadManager: DownloadManager by injectLazy() - - /** - * Property to get the queue from the download manager. - */ - private val downloadQueue: DownloadQueue - get() = downloadManager.queue +class DownloadPresenter( + private val downloadManager: DownloadManager = Injekt.get(), +) : BasePresenter() { private val _state = MutableStateFlow(emptyList()) val state = _state.asStateFlow() @@ -34,7 +28,7 @@ class DownloadPresenter : BasePresenter() { super.onCreate(savedState) presenterScope.launch { - downloadQueue.updates + downloadManager.queue.updates .catch { logcat(LogPriority.ERROR, it) } .map { downloads -> downloads @@ -49,20 +43,13 @@ class DownloadPresenter : BasePresenter() { } } - fun getDownloadStatusFlow() = downloadQueue.statusFlow() + fun getDownloadStatusFlow() = downloadManager.queue.statusFlow() + fun getDownloadProgressFlow() = downloadManager.queue.progressFlow() - fun getDownloadProgressFlow() = downloadQueue.progressFlow() - - /** - * Pauses the download queue. - */ fun pauseDownloads() { downloadManager.pauseDownloads() } - /** - * Clears the download queue. - */ fun clearQueue(context: Context) { DownloadService.stop(context) downloadManager.clearQueue() @@ -72,7 +59,7 @@ class DownloadPresenter : BasePresenter() { downloadManager.reorderQueue(downloads) } - fun cancelDownloads(downloads: List) { - downloadManager.deletePendingDownloads(downloads) + fun cancel(downloads: List) { + downloadManager.cancelQueuedDownloads(downloads) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt index 1703ec9832..c34fd1aedd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt @@ -496,7 +496,7 @@ class LibraryScreenModel( mangas.forEach { manga -> val chapters = getNextChapters.await(manga.id) .fastFilterNot { chapter -> - downloadManager.queue.any { chapter.id == it.chapter.id } || + downloadManager.getQueuedDownloadOrNull(chapter.id) != null || downloadManager.isChapterDownloaded( chapter.name, chapter.scanlator, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt index 759e153b2f..28b19548dd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt @@ -46,7 +46,6 @@ import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.network.HttpException import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceManager -import eu.kanade.tachiyomi.source.isLocal import eu.kanade.tachiyomi.ui.manga.track.TrackItem import eu.kanade.tachiyomi.util.chapter.getChapterSort import eu.kanade.tachiyomi.util.chapter.getNextUnread @@ -502,7 +501,7 @@ class MangaInfoScreenModel( val activeDownload = if (isLocal) { null } else { - downloadManager.queue.find { chapter.id == it.chapter.id } + downloadManager.getQueuedDownloadOrNull(chapter.id) } val downloaded = if (isLocal) { true @@ -668,8 +667,8 @@ class MangaInfoScreenModel( } fun cancelDownload(chapterId: Long) { - val activeDownload = downloadManager.queue.find { chapterId == it.chapter.id } ?: return - downloadManager.deletePendingDownloads(listOf(activeDownload)) + val activeDownload = downloadManager.getQueuedDownloadOrNull(chapterId) ?: return + downloadManager.cancelQueuedDownloads(listOf(activeDownload)) updateDownloadState(activeDownload.apply { status = Download.State.NOT_DOWNLOADED }) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index 113d68f4b8..23b7bc6959 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -339,7 +339,7 @@ class ReaderPresenter( newChapters.ref() oldChapters?.unref() - chapterToDownload = deleteChapterFromDownloadQueue(newChapters.currChapter) + chapterToDownload = cancelQueuedDownloads(newChapters.currChapter) viewerChaptersRelay.call(newChapters) } } @@ -489,9 +489,9 @@ class ReaderPresenter( * Removes [currentChapter] from download queue * if setting is enabled and [currentChapter] is queued for download */ - private fun deleteChapterFromDownloadQueue(currentChapter: ReaderChapter): Download? { - return downloadManager.getChapterDownloadOrNull(currentChapter.chapter.toDomainChapter()!!)?.also { - downloadManager.deletePendingDownloads(listOf(it)) + private fun cancelQueuedDownloads(currentChapter: ReaderChapter): Download? { + return downloadManager.getQueuedDownloadOrNull(currentChapter.chapter.id!!.toLong())?.also { + downloadManager.cancelQueuedDownloads(listOf(it)) } } @@ -875,7 +875,7 @@ class ReaderPresenter( val manga = manga ?: return presenterScope.launchNonCancellable { - downloadManager.enqueueDeleteChapters(listOf(chapter.chapter.toDomainChapter()!!), manga.toDomainManga()!!) + downloadManager.enqueueChaptersToDelete(listOf(chapter.chapter.toDomainChapter()!!), manga.toDomainManga()!!) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt index a6ea7aeef6..47e172d4e2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt @@ -116,7 +116,7 @@ class UpdatesScreenModel( private fun List.toUpdateItems(): List { return this.map { - val activeDownload = downloadManager.queue.find { download -> it.chapterId == download.chapter.id } + val activeDownload = downloadManager.getQueuedDownloadOrNull(it.chapterId) val downloaded = downloadManager.isChapterDownloaded( it.chapterName, it.scanlator, @@ -200,8 +200,8 @@ class UpdatesScreenModel( } private fun cancelDownload(chapterId: Long) { - val activeDownload = downloadManager.queue.find { chapterId == it.chapter.id } ?: return - downloadManager.deletePendingDownloads(listOf(activeDownload)) + val activeDownload = downloadManager.getQueuedDownloadOrNull(chapterId) ?: return + downloadManager.cancelQueuedDownloads(listOf(activeDownload)) updateDownloadState(activeDownload.apply { status = Download.State.NOT_DOWNLOADED }) }