diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt
index cedb24fb4..338d7b5d0 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt
@@ -6,8 +6,10 @@ import com.hippo.unifile.UniFile
 import eu.kanade.domain.download.service.DownloadPreferences
 import eu.kanade.domain.manga.model.Manga
 import eu.kanade.tachiyomi.data.database.models.Chapter
+import eu.kanade.tachiyomi.source.Source
 import eu.kanade.tachiyomi.source.SourceManager
-import kotlinx.coroutines.MainScope
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import uy.kohesive.injekt.Injekt
@@ -32,7 +34,7 @@ class DownloadCache(
     private val downloadPreferences: DownloadPreferences = Injekt.get(),
 ) {
 
-    private val scope = MainScope()
+    private val scope = CoroutineScope(Dispatchers.IO)
 
     /**
      * The interval after which this cache should be invalidated. 1 hour shouldn't cause major
@@ -50,8 +52,10 @@ class DownloadCache(
     init {
         downloadPreferences.downloadsDirectory().changes()
             .onEach {
-                lastRenew = 0L // invalidate cache
                 rootDownloadsDir = RootDirectory(getDirectoryFromPreference())
+
+                // Invalidate cache
+                lastRenew = 0L
             }
             .launchIn(scope)
     }
@@ -79,11 +83,11 @@ class DownloadCache(
 
         renewCache()
 
-        val sourceDir = rootDownloadsDir.files[sourceId]
+        val sourceDir = rootDownloadsDir.sourceDirs[sourceId]
         if (sourceDir != null) {
-            val mangaDir = sourceDir.files[provider.getMangaDirName(mangaTitle)]
+            val mangaDir = sourceDir.mangaDirs[provider.getMangaDirName(mangaTitle)]
             if (mangaDir != null) {
-                return provider.getValidChapterDirNames(chapterName, chapterScanlator).any { it in mangaDir.files }
+                return provider.getValidChapterDirNames(chapterName, chapterScanlator).any { it in mangaDir.chapterDirs }
             }
         }
         return false
@@ -97,11 +101,11 @@ class DownloadCache(
     fun getDownloadCount(manga: Manga): Int {
         renewCache()
 
-        val sourceDir = rootDownloadsDir.files[manga.source]
+        val sourceDir = rootDownloadsDir.sourceDirs[manga.source]
         if (sourceDir != null) {
-            val mangaDir = sourceDir.files[provider.getMangaDirName(/* SY --> */ manga.ogTitle /* SY <-- */)]
+            val mangaDir = sourceDir.mangaDirs[provider.getMangaDirName(/* SY --> */ manga.ogTitle /* SY <-- */)]
             if (mangaDir != null) {
-                return mangaDir.files.size
+                return mangaDir.chapterDirs.size
             }
         }
         return 0
@@ -117,24 +121,24 @@ class DownloadCache(
     @Synchronized
     fun addChapter(chapterDirName: String, mangaUniFile: UniFile, manga: Manga) {
         // Retrieve the cached source directory or cache a new one
-        var sourceDir = rootDownloadsDir.files[manga.source]
+        var sourceDir = rootDownloadsDir.sourceDirs[manga.source]
         if (sourceDir == null) {
             val source = sourceManager.get(manga.source) ?: return
             val sourceUniFile = provider.findSourceDir(source) ?: return
             sourceDir = SourceDirectory(sourceUniFile)
-            rootDownloadsDir.files += manga.source to sourceDir
+            rootDownloadsDir.sourceDirs += manga.source to sourceDir
         }
 
         // Retrieve the cached manga directory or cache a new one
         val mangaDirName = provider.getMangaDirName(/* SY --> */ manga.ogTitle /* SY <-- */)
-        var mangaDir = sourceDir.files[mangaDirName]
+        var mangaDir = sourceDir.mangaDirs[mangaDirName]
         if (mangaDir == null) {
             mangaDir = MangaDirectory(mangaUniFile)
-            sourceDir.files += mangaDirName to mangaDir
+            sourceDir.mangaDirs += mangaDirName to mangaDir
         }
 
         // Save the chapter directory
-        mangaDir.files += chapterDirName
+        mangaDir.chapterDirs += chapterDirName
     }
 
     /**
@@ -145,22 +149,22 @@ class DownloadCache(
      */
     @Synchronized
     fun removeChapter(chapter: Chapter, manga: Manga) {
-        val sourceDir = rootDownloadsDir.files[manga.source] ?: return
-        val mangaDir = sourceDir.files[provider.getMangaDirName(/* SY --> */ manga.ogTitle /* SY <-- */)] ?: return
+        val sourceDir = rootDownloadsDir.sourceDirs[manga.source] ?: return
+        val mangaDir = sourceDir.mangaDirs[provider.getMangaDirName(/* SY --> */ manga.ogTitle /* SY <-- */)] ?: return
         provider.getValidChapterDirNames(chapter.name, chapter.scanlator).forEach {
-            if (it in mangaDir.files) {
-                mangaDir.files -= it
+            if (it in mangaDir.chapterDirs) {
+                mangaDir.chapterDirs -= it
             }
         }
     }
 
     // SY -->
     fun removeFolders(folders: List<String>, manga: Manga) {
-        val sourceDir = rootDownloadsDir.files[manga.source] ?: return
-        val mangaDir = sourceDir.files[provider.getMangaDirName(manga.ogTitle)] ?: return
+        val sourceDir = rootDownloadsDir.sourceDirs[manga.source] ?: return
+        val mangaDir = sourceDir.mangaDirs[provider.getMangaDirName(manga.ogTitle)] ?: return
         folders.forEach { chapter ->
-            if (chapter in mangaDir.files) {
-                mangaDir.files -= chapter
+            if (chapter in mangaDir.chapterDirs) {
+                mangaDir.chapterDirs -= chapter
             }
         }
     }
@@ -175,12 +179,12 @@ class DownloadCache(
      */
     @Synchronized
     fun removeChapters(chapters: List<Chapter>, manga: Manga) {
-        val sourceDir = rootDownloadsDir.files[manga.source] ?: return
-        val mangaDir = sourceDir.files[provider.getMangaDirName(/* SY --> */ manga.ogTitle /* SY <-- */)] ?: return
+        val sourceDir = rootDownloadsDir.sourceDirs[manga.source] ?: return
+        val mangaDir = sourceDir.mangaDirs[provider.getMangaDirName(/* SY --> */ manga.ogTitle /* SY <-- */)] ?: return
         chapters.forEach { chapter ->
             provider.getValidChapterDirNames(chapter.name, chapter.scanlator).forEach {
-                if (it in mangaDir.files) {
-                    mangaDir.files -= it
+                if (it in mangaDir.chapterDirs) {
+                    mangaDir.chapterDirs -= it
                 }
             }
         }
@@ -193,10 +197,19 @@ class DownloadCache(
      */
     @Synchronized
     fun removeManga(manga: Manga) {
-        val sourceDir = rootDownloadsDir.files[manga.source] ?: return
+        val sourceDir = rootDownloadsDir.sourceDirs[manga.source] ?: return
         val mangaDirName = provider.getMangaDirName(/* SY --> */ manga.ogTitle /* SY <-- */)
-        if (mangaDirName in sourceDir.files) {
-            sourceDir.files -= mangaDirName
+        if (mangaDirName in sourceDir.mangaDirs) {
+            sourceDir.mangaDirs -= mangaDirName
+        }
+    }
+
+    @Synchronized
+    fun removeSourceIfEmpty(source: Source) {
+        val sourceDir = provider.findSourceDir(source)
+        if (sourceDir?.listFiles()?.isEmpty() == true) {
+            sourceDir.delete()
+            rootDownloadsDir.sourceDirs -= source.id
         }
     }
 
@@ -235,14 +248,14 @@ class DownloadCache(
                 }?.id
             }
 
-        rootDownloadsDir.files = sourceDirs
+        rootDownloadsDir.sourceDirs = sourceDirs
 
         sourceDirs.values.forEach { sourceDir ->
             val mangaDirs = sourceDir.dir.listFiles()
                 .orEmpty()
                 .associateNotNullKeys { it.name to MangaDirectory(it) }
 
-            sourceDir.files = mangaDirs
+            sourceDir.mangaDirs = mangaDirs
 
             mangaDirs.values.forEach { mangaDir ->
                 val chapterDirs = mangaDir.dir.listFiles()
@@ -254,7 +267,7 @@ class DownloadCache(
                     }
                     .toHashSet()
 
-                mangaDir.files = chapterDirs
+                mangaDir.chapterDirs = chapterDirs
             }
         }
 
@@ -290,7 +303,7 @@ class DownloadCache(
  */
 private class RootDirectory(
     val dir: UniFile,
-    var files: Map<Long, SourceDirectory> = hashMapOf(),
+    var sourceDirs: Map<Long, SourceDirectory> = hashMapOf(),
 )
 
 /**
@@ -298,7 +311,7 @@ private class RootDirectory(
  */
 private class SourceDirectory(
     val dir: UniFile,
-    var files: Map<String, MangaDirectory> = hashMapOf(),
+    var mangaDirs: Map<String, MangaDirectory> = hashMapOf(),
 )
 
 /**
@@ -306,5 +319,5 @@ private class SourceDirectory(
  */
 private class MangaDirectory(
     val dir: UniFile,
-    var files: Set<String> = hashSetOf(),
+    var chapterDirs: Set<String> = hashSetOf(),
 )
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 4ee3abe44..49f46e7f4 100755
--- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt
@@ -289,10 +289,7 @@ class DownloadManager(
             }
 
             // Delete source directory if empty
-            val sourceDir = provider.findSourceDir(source)
-            if (sourceDir?.listFiles()?.isEmpty() == true) {
-                sourceDir.delete()
-            }
+            cache.removeSourceIfEmpty(source)
         }
 
         return filteredChapters
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
index 10117359e..6f98adb65 100755
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
@@ -493,34 +493,44 @@ class LibraryPresenter(
      * @return an observable of the categories and its manga.
      */
     private fun getLibraryFlow(): Flow<Library> {
-        val categoriesFlow = getCategories.subscribe()
-        val libraryMangasFlow = getLibraryManga.subscribe()
-            .map { list ->
-                list.map { libraryManga ->
+        val libraryMangasFlow = combine(
+            getLibraryManga.subscribe(),
+            libraryPreferences.downloadBadge().changes(),
+        ) { libraryMangaList, downloadBadgePref ->
+            libraryMangaList
+                .map { libraryManga ->
                     // Display mode based on user preference: take it from global library setting or category
                     LibraryItem(libraryManga).apply {
-                        downloadCount = /* SY --> */ if (libraryManga.manga.source == MERGED_SOURCE_ID) {
-                            runBlocking {
-                                getMergedMangaById.await(libraryManga.manga.id)
-                            }.sumOf { downloadManager.getDownloadCount(it) }.toLong()
+                        downloadCount = if (downloadBadgePref) {
+                            // SY -->
+                            if (libraryManga.manga.source == MERGED_SOURCE_ID) {
+                                runBlocking {
+                                    getMergedMangaById.await(libraryManga.manga.id)
+                                }.sumOf { downloadManager.getDownloadCount(it) }.toLong()
+                            } else {
+                                downloadManager.getDownloadCount(libraryManga.manga).toLong()
+                            }
+                            // SY <--
                         } else {
-                            downloadManager.getDownloadCount(libraryManga.manga).toLong()
-                        } /* SY <-- */
+                            0
+                        }
                         unreadCount = libraryManga.unreadCount
                         isLocal = libraryManga.manga.isLocal()
                         sourceLanguage = sourceManager.getOrStub(libraryManga.manga.source).lang
                     }
-                }.groupBy { it.libraryManga.category }
-            }
-        return combine(categoriesFlow, libraryMangasFlow) { dbCategories, libraryManga ->
-            val categories = if (libraryManga.isNotEmpty() && libraryManga.containsKey(0).not()) {
-                dbCategories.filterNot { it.isSystemCategory }
+                }
+                .groupBy { it.libraryManga.category }
+        }
+
+        return combine(getCategories.subscribe(), libraryMangasFlow) { categories, libraryManga ->
+            val displayCategories = if (libraryManga.isNotEmpty() && libraryManga.containsKey(0).not()) {
+                categories.filterNot { it.isSystemCategory }
             } else {
-                dbCategories
+                categories
             }
 
             // SY -->
-            state.ogCategories = categories
+            state.ogCategories = displayCategories
             // SY <--
             Library(categories, libraryManga)
         }