浏览代码

Account for skipped entries when showing large updates warning

Closes #6159
arkon 1 年之前
父节点
当前提交
7ed99fbbd6

+ 84 - 73
app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt

@@ -186,7 +186,40 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
                 .distinctBy { it.manga.id }
         }
 
+        val restrictions = libraryPreferences.autoUpdateMangaRestrictions().get()
+        val skippedUpdates = mutableListOf<Pair<Manga, String?>>()
+        val fetchWindow = fetchInterval.getWindow(ZonedDateTime.now())
+
         mangaToUpdate = listToUpdate
+            .filter {
+                when {
+                    it.manga.updateStrategy != UpdateStrategy.ALWAYS_UPDATE -> {
+                        skippedUpdates.add(it.manga to context.getString(R.string.skipped_reason_not_always_update))
+                        false
+                    }
+
+                    MANGA_NON_COMPLETED in restrictions && it.manga.status.toInt() == SManga.COMPLETED -> {
+                        skippedUpdates.add(it.manga to context.getString(R.string.skipped_reason_completed))
+                        false
+                    }
+
+                    MANGA_HAS_UNREAD in restrictions && it.unreadCount != 0L -> {
+                        skippedUpdates.add(it.manga to context.getString(R.string.skipped_reason_not_caught_up))
+                        false
+                    }
+
+                    MANGA_NON_READ in restrictions && it.totalChapters > 0L && !it.hasStarted -> {
+                        skippedUpdates.add(it.manga to context.getString(R.string.skipped_reason_not_started))
+                        false
+                    }
+
+                    MANGA_OUTSIDE_RELEASE_PERIOD in restrictions && it.manga.nextUpdate > fetchWindow.second -> {
+                        skippedUpdates.add(it.manga to context.getString(R.string.skipped_reason_not_in_release_period))
+                        false
+                    }
+                    else -> true
+                }
+            }
             .sortedBy { it.manga.title }
 
         // Warn when excessively checking a single source
@@ -197,6 +230,17 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
         if (maxUpdatesFromSource > MANGA_PER_SOURCE_QUEUE_WARNING_THRESHOLD) {
             notifier.showQueueSizeWarningNotification()
         }
+
+        if (skippedUpdates.isNotEmpty()) {
+            // TODO: surface skipped reasons to user?
+            logcat {
+                skippedUpdates
+                    .groupBy { it.second }
+                    .map { (reason, entries) -> "$reason: [${entries.map { it.first.title }.sorted().joinToString()}]" }
+                    .joinToString()
+            }
+            notifier.showUpdateSkippedNotification(skippedUpdates.size)
+        }
     }
 
     /**
@@ -212,10 +256,8 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
         val progressCount = AtomicInteger(0)
         val currentlyUpdatingManga = CopyOnWriteArrayList<Manga>()
         val newUpdates = CopyOnWriteArrayList<Pair<Manga, Array<Chapter>>>()
-        val skippedUpdates = CopyOnWriteArrayList<Pair<Manga, String?>>()
         val failedUpdates = CopyOnWriteArrayList<Pair<Manga, String?>>()
         val hasDownloads = AtomicBoolean(false)
-        val restrictions = libraryPreferences.autoUpdateMangaRestrictions().get()
         val fetchWindow = fetchInterval.getWindow(ZonedDateTime.now())
 
         coroutineScope {
@@ -237,49 +279,30 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
                                     progressCount,
                                     manga,
                                 ) {
-                                    when {
-                                        manga.updateStrategy != UpdateStrategy.ALWAYS_UPDATE ->
-                                            skippedUpdates.add(manga to context.getString(R.string.skipped_reason_not_always_update))
-
-                                        MANGA_NON_COMPLETED in restrictions && manga.status.toInt() == SManga.COMPLETED ->
-                                            skippedUpdates.add(manga to context.getString(R.string.skipped_reason_completed))
-
-                                        MANGA_HAS_UNREAD in restrictions && libraryManga.unreadCount != 0L ->
-                                            skippedUpdates.add(manga to context.getString(R.string.skipped_reason_not_caught_up))
-
-                                        MANGA_NON_READ in restrictions && libraryManga.totalChapters > 0L && !libraryManga.hasStarted ->
-                                            skippedUpdates.add(manga to context.getString(R.string.skipped_reason_not_started))
-
-                                        MANGA_OUTSIDE_RELEASE_PERIOD in restrictions && manga.nextUpdate > fetchWindow.second ->
-                                            skippedUpdates.add(manga to context.getString(R.string.skipped_reason_not_in_release_period))
-
-                                        else -> {
-                                            try {
-                                                val newChapters = updateManga(manga, fetchWindow)
-                                                    .sortedByDescending { it.sourceOrder }
-
-                                                if (newChapters.isNotEmpty()) {
-                                                    val categoryIds = getCategories.await(manga.id).map { it.id }
-                                                    if (manga.shouldDownloadNewChapters(categoryIds, downloadPreferences)) {
-                                                        downloadChapters(manga, newChapters)
-                                                        hasDownloads.set(true)
-                                                    }
-
-                                                    libraryPreferences.newUpdatesCount().getAndSet { it + newChapters.size }
-
-                                                    // Convert to the manga that contains new chapters
-                                                    newUpdates.add(manga to newChapters.toTypedArray())
-                                                }
-                                            } catch (e: Throwable) {
-                                                val errorMessage = when (e) {
-                                                    is NoChaptersException -> context.getString(R.string.no_chapters_error)
-                                                    // failedUpdates will already have the source, don't need to copy it into the message
-                                                    is SourceNotInstalledException -> context.getString(R.string.loader_not_implemented_error)
-                                                    else -> e.message
-                                                }
-                                                failedUpdates.add(manga to errorMessage)
+                                    try {
+                                        val newChapters = updateManga(manga, fetchWindow)
+                                            .sortedByDescending { it.sourceOrder }
+
+                                        if (newChapters.isNotEmpty()) {
+                                            val categoryIds = getCategories.await(manga.id).map { it.id }
+                                            if (manga.shouldDownloadNewChapters(categoryIds, downloadPreferences)) {
+                                                downloadChapters(manga, newChapters)
+                                                hasDownloads.set(true)
                                             }
+
+                                            libraryPreferences.newUpdatesCount().getAndSet { it + newChapters.size }
+
+                                            // Convert to the manga that contains new chapters
+                                            newUpdates.add(manga to newChapters.toTypedArray())
+                                        }
+                                    } catch (e: Throwable) {
+                                        val errorMessage = when (e) {
+                                            is NoChaptersException -> context.getString(R.string.no_chapters_error)
+                                            // failedUpdates will already have the source, don't need to copy it into the message
+                                            is SourceNotInstalledException -> context.getString(R.string.loader_not_implemented_error)
+                                            else -> e.message
                                         }
+                                        failedUpdates.add(manga to errorMessage)
                                     }
 
                                     if (libraryPreferences.autoUpdateTrackers().get()) {
@@ -309,16 +332,6 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
                 errorFile.getUriCompat(context),
             )
         }
-        if (skippedUpdates.isNotEmpty()) {
-            // TODO: surface skipped reasons to user
-            logcat {
-                skippedUpdates
-                    .groupBy { it.second }
-                    .map { (reason, entries) -> "$reason: [${entries.map { it.first.title }.sorted().joinToString()}]" }
-                    .joinToString()
-            }
-            notifier.showUpdateSkippedNotification(skippedUpdates.size)
-        }
     }
 
     private fun downloadChapters(manga: Manga, chapters: List<Chapter>) {
@@ -428,29 +441,27 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
         completed: AtomicInteger,
         manga: Manga,
         block: suspend () -> Unit,
-    ) {
-        coroutineScope {
-            ensureActive()
-
-            updatingManga.add(manga)
-            notifier.showProgressNotification(
-                updatingManga,
-                completed.get(),
-                mangaToUpdate.size,
-            )
+    ) = coroutineScope {
+        ensureActive()
+
+        updatingManga.add(manga)
+        notifier.showProgressNotification(
+            updatingManga,
+            completed.get(),
+            mangaToUpdate.size,
+        )
 
-            block()
+        block()
 
-            ensureActive()
+        ensureActive()
 
-            updatingManga.remove(manga)
-            completed.getAndIncrement()
-            notifier.showProgressNotification(
-                updatingManga,
-                completed.get(),
-                mangaToUpdate.size,
-            )
-        }
+        updatingManga.remove(manga)
+        completed.getAndIncrement()
+        notifier.showProgressNotification(
+            updatingManga,
+            completed.get(),
+            mangaToUpdate.size,
+        )
     }
 
     /**

+ 5 - 1
app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateNotifier.kt

@@ -30,10 +30,14 @@ import tachiyomi.core.util.lang.launchUI
 import tachiyomi.domain.chapter.model.Chapter
 import tachiyomi.domain.manga.model.Manga
 import uy.kohesive.injekt.injectLazy
+import java.text.NumberFormat
 
 class LibraryUpdateNotifier(private val context: Context) {
 
     private val preferences: SecurityPreferences by injectLazy()
+    private val percentFormatter = NumberFormat.getPercentInstance().apply {
+        maximumFractionDigits = 0
+    }
 
     /**
      * Pending intent of action that cancels the library update
@@ -78,7 +82,7 @@ class LibraryUpdateNotifier(private val context: Context) {
         } else {
             val updatingText = manga.joinToString("\n") { it.title.chop(40) }
             progressNotificationBuilder
-                .setContentTitle(context.getString(R.string.notification_updating, current, total))
+                .setContentTitle(context.getString(R.string.notification_updating_progress, percentFormatter.format(current.toFloat() / total)))
                 .setStyle(NotificationCompat.BigTextStyle().bigText(updatingText))
         }
 

+ 1 - 1
i18n/src/main/res/values/strings.xml

@@ -837,7 +837,7 @@
 
     <!-- Library update service notifications -->
     <string name="notification_check_updates">Checking for new chapters</string>
-    <string name="notification_updating">Updating library… (%1$d/%2$d)</string>
+    <string name="notification_updating_progress">Updating library… (%s)</string>
     <string name="notification_size_warning">Large updates harm sources and may lead to slower updates and also increased battery usage. Tap to learn more.</string>
     <string name="notification_new_chapters">New chapters found</string>
     <plurals name="notification_new_chapters_summary">