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 4868d8d6f5..67e78d03f0 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
@@ -48,6 +48,8 @@ class DownloadCache(
private val scope = CoroutineScope(Dispatchers.IO)
+ private val notifier by lazy { DownloadNotifier(context) }
+
/**
* The interval after which this cache should be invalidated. 1 hour shouldn't cause major
* issues, as the cache is only used for UI feedback.
@@ -241,56 +243,62 @@ class DownloadCache(
}
renewalJob = scope.launchIO {
- var sources = getSources()
+ try {
+ notifier.onCacheProgress()
- // Try to wait until extensions and sources have loaded
- withTimeout(30.seconds) {
- while (!extensionManager.isInitialized) {
- delay(2.seconds)
- }
+ var sources = getSources()
- while (sources.isEmpty()) {
- delay(2.seconds)
- sources = getSources()
- }
- }
+ // Try to wait until extensions and sources have loaded
+ withTimeout(30.seconds) {
+ while (!extensionManager.isInitialized) {
+ delay(2.seconds)
+ }
- val sourceDirs = rootDownloadsDir.dir.listFiles().orEmpty()
- .associate { it.name to SourceDirectory(it) }
- .mapNotNullKeys { entry ->
- sources.find {
- provider.getSourceDirName(it).equals(entry.key, ignoreCase = true)
- }?.id
- }
-
- rootDownloadsDir.sourceDirs = sourceDirs
-
- sourceDirs.values
- .map { sourceDir ->
- async {
- val mangaDirs = sourceDir.dir.listFiles().orEmpty()
- .filterNot { it.name.isNullOrBlank() }
- .associate { it.name!! to MangaDirectory(it) }
-
- sourceDir.mangaDirs = ConcurrentHashMap(mangaDirs)
-
- mangaDirs.values.forEach { mangaDir ->
- val chapterDirs = mangaDir.dir.listFiles().orEmpty()
- .mapNotNull { chapterDir ->
- chapterDir.name
- ?.replace(".cbz", "")
- ?.takeUnless { it.endsWith(Downloader.TMP_DIR_SUFFIX) }
- }
- .toMutableSet()
-
- mangaDir.chapterDirs = chapterDirs
- }
+ while (sources.isEmpty()) {
+ delay(2.seconds)
+ sources = getSources()
}
}
- .awaitAll()
- lastRenew = System.currentTimeMillis()
- notifyChanges()
+ val sourceDirs = rootDownloadsDir.dir.listFiles().orEmpty()
+ .associate { it.name to SourceDirectory(it) }
+ .mapNotNullKeys { entry ->
+ sources.find {
+ provider.getSourceDirName(it).equals(entry.key, ignoreCase = true)
+ }?.id
+ }
+
+ rootDownloadsDir.sourceDirs = sourceDirs
+
+ sourceDirs.values
+ .map { sourceDir ->
+ async {
+ val mangaDirs = sourceDir.dir.listFiles().orEmpty()
+ .filterNot { it.name.isNullOrBlank() }
+ .associate { it.name!! to MangaDirectory(it) }
+
+ sourceDir.mangaDirs = ConcurrentHashMap(mangaDirs)
+
+ mangaDirs.values.forEach { mangaDir ->
+ val chapterDirs = mangaDir.dir.listFiles().orEmpty()
+ .mapNotNull { chapterDir ->
+ chapterDir.name
+ ?.replace(".cbz", "")
+ ?.takeUnless { it.endsWith(Downloader.TMP_DIR_SUFFIX) }
+ }
+ .toMutableSet()
+
+ mangaDir.chapterDirs = chapterDirs
+ }
+ }
+ }
+ .awaitAll()
+
+ lastRenew = System.currentTimeMillis()
+ notifyChanges()
+ } finally {
+ notifier.dismissCacheProgress()
+ }
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt
index e7621aea37..be54abc30b 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt
@@ -45,6 +45,17 @@ internal class DownloadNotifier(private val context: Context) {
}
}
+ private val cacheNotificationBuilder by lazy {
+ context.notificationBuilder(Notifications.CHANNEL_DOWNLOADER_CACHE) {
+ setSmallIcon(R.drawable.ic_tachi)
+ setContentTitle(context.getString(R.string.download_notifier_cache_renewal))
+ setProgress(100, 100, true)
+ setOngoing(true)
+ setAutoCancel(false)
+ setOnlyAlertOnce(true)
+ }
+ }
+
/**
* Status of download. Used for correct notification icon.
*/
@@ -233,4 +244,14 @@ internal class DownloadNotifier(private val context: Context) {
errorThrown = true
isDownloading = false
}
+
+ fun onCacheProgress() {
+ with(cacheNotificationBuilder) {
+ show(Notifications.ID_DOWNLOAD_CACHE)
+ }
+ }
+
+ fun dismissCacheProgress() {
+ context.notificationManager.cancel(Notifications.ID_DOWNLOAD_CACHE)
+ }
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt
index bccc31140d..d89df8dab6 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt
@@ -42,6 +42,8 @@ object Notifications {
const val ID_DOWNLOAD_CHAPTER_COMPLETE = -203
const val CHANNEL_DOWNLOADER_ERROR = "downloader_error_channel"
const val ID_DOWNLOAD_CHAPTER_ERROR = -202
+ const val CHANNEL_DOWNLOADER_CACHE = "downloader_cache_renewal"
+ const val ID_DOWNLOAD_CACHE = -204
/**
* Notification channel and ids used by the library updater.
@@ -159,6 +161,11 @@ object Notifications {
setGroup(GROUP_DOWNLOADER)
setShowBadge(false)
},
+ buildNotificationChannel(CHANNEL_DOWNLOADER_CACHE, IMPORTANCE_LOW) {
+ setName(context.getString(R.string.channel_downloader_cache))
+ setGroup(GROUP_DOWNLOADER)
+ setShowBadge(false)
+ },
buildNotificationChannel(CHANNEL_BACKUP_RESTORE_PROGRESS, IMPORTANCE_LOW) {
setName(context.getString(R.string.channel_progress))
setGroup(GROUP_BACKUP_RESTORE)
diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml
index 17ffdfc4f7..d85d7b1dbf 100644
--- a/i18n/src/main/res/values/strings.xml
+++ b/i18n/src/main/res/values/strings.xml
@@ -863,6 +863,7 @@
Page %d not found while splitting
Couldn\'t find file path of page %d
Couldn\'t split downloaded image
+ Indexing downloads
Common
@@ -873,6 +874,7 @@
Chapter updates
App updates
Extension updates
+ Download cache
Crash logs