From 9e0e2db25dbae3bebdabcde8763fe3a42db81ad4 Mon Sep 17 00:00:00 2001 From: Jobobby04 Date: Tue, 18 Aug 2020 18:55:00 -0400 Subject: [PATCH] Add dynamic category library update upgrades --- .../data/library/LibraryUpdateService.kt | 61 ++++++++++++++++++- .../data/preference/PreferenceKeys.kt | 2 + .../data/preference/PreferenceValues.kt | 8 +++ .../data/preference/PreferencesHelper.kt | 2 + .../tachiyomi/data/track/TrackManager.kt | 26 ++++++++ .../ui/library/LibraryCategoryView.kt | 29 ++++++++- .../tachiyomi/ui/library/LibraryPresenter.kt | 45 ++++---------- .../ui/setting/SettingsLibraryController.kt | 20 ++++++ app/src/main/res/values/strings_sy.xml | 4 ++ 9 files changed, 160 insertions(+), 37 deletions(-) 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 94b7d9d8b..bd024b27f 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt @@ -17,10 +17,12 @@ import eu.kanade.tachiyomi.data.download.DownloadService import eu.kanade.tachiyomi.data.library.LibraryUpdateRanker.rankingScheme import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start import eu.kanade.tachiyomi.data.notification.Notifications +import eu.kanade.tachiyomi.data.preference.PreferenceValues import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.model.SManga +import eu.kanade.tachiyomi.ui.library.LibraryGroup import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource import eu.kanade.tachiyomi.util.prepUpdateCover import eu.kanade.tachiyomi.util.shouldDownloadNewChapters @@ -28,6 +30,7 @@ import eu.kanade.tachiyomi.util.storage.getUriCompat import eu.kanade.tachiyomi.util.system.acquireWakeLock import eu.kanade.tachiyomi.util.system.isServiceRunning import exh.LIBRARY_UPDATE_EXCLUDED_SOURCES +import exh.util.nullIfBlank import java.io.File import java.util.concurrent.atomic.AtomicInteger import rx.Observable @@ -87,6 +90,14 @@ class LibraryUpdateService( */ const val KEY_TARGET = "target" + // SY --> + /** + * Key for group to update. + */ + const val KEY_GROUP = "group" + const val KEY_GROUP_EXTRA = "group_extra" + // SY <-- + /** * Returns the status of the service. * @@ -106,11 +117,15 @@ class LibraryUpdateService( * @param target defines what should be updated. * @return true if service newly started, false otherwise */ - fun start(context: Context, category: Category? = null, target: Target = Target.CHAPTERS): Boolean { + fun start(context: Context, category: Category? = null, target: Target = Target.CHAPTERS /* SY --> */, group: Int = LibraryGroup.BY_DEFAULT, groupExtra: String? = null /* SY <-- */): Boolean { if (!isRunning(context)) { val intent = Intent(context, LibraryUpdateService::class.java).apply { putExtra(KEY_TARGET, target) category?.let { putExtra(KEY_CATEGORY, it.id) } + // SY --> + putExtra(KEY_GROUP, group) + groupExtra?.let { putExtra(KEY_GROUP_EXTRA, it) } + // SY <-- } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { context.startService(intent) @@ -221,10 +236,15 @@ class LibraryUpdateService( */ fun getMangaToUpdate(intent: Intent, target: Target): List { val categoryId = intent.getIntExtra(KEY_CATEGORY, -1) + // SY --> + val group = intent.getIntExtra(KEY_GROUP, LibraryGroup.BY_DEFAULT) + val groupLibraryUpdateType = preferences.groupLibraryUpdateType().get() + // SY <-- var listToUpdate = if (categoryId != -1) { db.getLibraryMangas().executeAsBlocking().filter { it.category == categoryId } - } else { + // SY --> + } else if (group == LibraryGroup.BY_DEFAULT || groupLibraryUpdateType == PreferenceValues.GroupLibraryMode.GLOBAL || (groupLibraryUpdateType == PreferenceValues.GroupLibraryMode.ALL_BUT_UNGROUPED && group == LibraryGroup.UNGROUPED)) { val categoriesToUpdate = preferences.libraryUpdateCategories().get().map(String::toInt) if (categoriesToUpdate.isNotEmpty()) { db.getLibraryMangas().executeAsBlocking() @@ -233,6 +253,43 @@ class LibraryUpdateService( } else { db.getLibraryMangas().executeAsBlocking().distinctBy { it.id } } + } else { + val libraryManga = db.getLibraryMangas().executeAsBlocking().distinctBy { it.id } + when (group) { + LibraryGroup.BY_TRACK_STATUS -> { + val trackingExtra = intent.getStringExtra(KEY_GROUP_EXTRA)?.toIntOrNull() ?: -1 + libraryManga.filter { + val loggedServices = trackManager.services.filter { it.isLogged } + val status: String = { + val tracks = db.getTracks(it).executeAsBlocking() + val track = tracks.find { track -> + loggedServices.any { it.id == track?.sync_id } + } + val service = loggedServices.find { it.id == track?.sync_id } + if (track != null && service != null) { + service.getStatus(track.status) + } else { + "not tracked" + } + }() + trackManager.mapTrackingOrder(status, applicationContext) == trackingExtra + } + } + LibraryGroup.BY_SOURCE -> { + val sourceExtra = intent.getStringExtra(KEY_GROUP_EXTRA).nullIfBlank() + val source = sourceManager.getCatalogueSources().find { it.name == sourceExtra } + if (source != null) libraryManga.filter { it.source == source.id } else emptyList() + } + LibraryGroup.BY_STATUS -> { + val statusExtra = intent.getStringExtra(KEY_GROUP_EXTRA)?.toIntOrNull() ?: -1 + libraryManga.filter { + it.status == statusExtra + } + } + LibraryGroup.UNGROUPED -> libraryManga + else -> libraryManga + } + // SY <-- } if (target == Target.CHAPTERS && preferences.updateOnlyNonCompleted()) { listToUpdate = listToUpdate.filter { it.status != SManga.COMPLETED } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index c92388656..7c3869397 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -282,4 +282,6 @@ object PreferenceKeys { const val groupLibraryBy = "group_library_by" const val continuousVerticalTappingByPage = "continuous_vertical_tapping_by_page" + + const val groupLibraryUpdateType = "group_library_update_type" } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt index 60b85705e..3ca47e9c1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt @@ -46,4 +46,12 @@ object PreferenceValues { PARTIAL, BLOCKED } + + // SY --> + enum class GroupLibraryMode { + GLOBAL, + ALL_BUT_UNGROUPED, + ALL + } + // SY <-- } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 89c1aed1f..94ac50aaa 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -387,4 +387,6 @@ class PreferencesHelper(val context: Context) { fun groupLibraryBy() = flowPrefs.getInt(Keys.groupLibraryBy, 0) fun continuousVerticalTappingByPage() = flowPrefs.getBoolean(Keys.continuousVerticalTappingByPage, false) + + fun groupLibraryUpdateType() = flowPrefs.getEnum(Keys.groupLibraryUpdateType, Values.GroupLibraryMode.GLOBAL) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackManager.kt index 173a6ffd6..41cfd20bf 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackManager.kt @@ -15,6 +15,16 @@ class TrackManager(context: Context) { const val KITSU = 3 const val SHIKIMORI = 4 const val BANGUMI = 5 + + // SY --> + const val READING = 1 + const val REREADING = 2 + const val PLANTOREAD = 3 + const val PAUSED = 4 + const val COMPLETED = 5 + const val DROPPED = 6 + const val OTHER = 7 + // SY <-- } val myAnimeList = MyAnimeList(context, MYANIMELIST) @@ -32,4 +42,20 @@ class TrackManager(context: Context) { fun getService(id: Int) = services.find { it.id == id } fun hasLoggedServices() = services.any { it.isLogged } + + // SY --> + fun mapTrackingOrder(status: String, context: Context): Int { + with(context) { + return when (status) { + getString(eu.kanade.tachiyomi.R.string.reading), getString(eu.kanade.tachiyomi.R.string.currently_reading) -> READING + getString(eu.kanade.tachiyomi.R.string.repeating) -> REREADING + getString(eu.kanade.tachiyomi.R.string.plan_to_read), getString(eu.kanade.tachiyomi.R.string.want_to_read) -> PLANTOREAD + getString(eu.kanade.tachiyomi.R.string.on_hold), getString(eu.kanade.tachiyomi.R.string.paused) -> PAUSED + getString(eu.kanade.tachiyomi.R.string.completed) -> COMPLETED + getString(eu.kanade.tachiyomi.R.string.dropped) -> DROPPED + else -> OTHER + } + } + } + // SY <-- } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt index 26a99d271..c4c0e3ae6 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt @@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.library.LibraryUpdateService +import eu.kanade.tachiyomi.data.preference.PreferenceValues import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.ui.category.CategoryAdapter @@ -128,9 +129,33 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att swipe_refresh.setDistanceToTriggerSync((2 * 64 * resources.displayMetrics.density).toInt()) swipe_refresh.refreshes() .onEach { - if (LibraryUpdateService.start(context, if (preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT) category else null)) { - context.toast(R.string.updating_category) + // SY --> + if (LibraryUpdateService.start( + context, + if (controller.presenter.groupType == LibraryGroup.BY_DEFAULT) category else null, + group = controller.presenter.groupType, + groupExtra = when (controller.presenter.groupType) { + LibraryGroup.BY_DEFAULT -> null + LibraryGroup.BY_SOURCE -> category.name + LibraryGroup.BY_STATUS, LibraryGroup.BY_TRACK_STATUS -> category.id.toString() + else -> null + } + ) + ) { + context.toast( + when { + controller.presenter.groupType == LibraryGroup.BY_DEFAULT || + (preferences.groupLibraryUpdateType().get() == PreferenceValues.GroupLibraryMode.ALL) -> R.string.updating_category + ( + controller.presenter.groupType == LibraryGroup.UNGROUPED && + preferences.groupLibraryUpdateType().get() == PreferenceValues.GroupLibraryMode.ALL_BUT_UNGROUPED + ) || + preferences.groupLibraryUpdateType().get() == PreferenceValues.GroupLibraryMode.GLOBAL -> R.string.updating_library + else -> R.string.updating_category + } + ) } + // SY <-- // It can be a very long operation, so we disable swipe refresh and show a toast. swipe_refresh.isRefreshing = false 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 8e139b55d..909c6c4ae 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 @@ -59,7 +59,8 @@ class LibraryPresenter( private val sourceManager: SourceManager = Injekt.get(), private val downloadManager: DownloadManager = Injekt.get(), // SY --> - private val customMangaManager: CustomMangaManager = Injekt.get() + private val customMangaManager: CustomMangaManager = Injekt.get(), + private val trackManager: TrackManager = Injekt.get() // SY <-- ) : BasePresenter() { @@ -94,12 +95,12 @@ class LibraryPresenter( // SY --> val favoritesSync = FavoritesSyncHelper(context) - private var groupType = preferences.groupLibraryBy().get() + var groupType = preferences.groupLibraryBy().get() private val libraryIsGrouped get() = groupType != LibraryGroup.UNGROUPED - private val loggedServices by lazy { Injekt.get().services.filter { it.isLogged } } + private val loggedServices by lazy { trackManager.services.filter { it.isLogged } } /** * Relay used to apply the UI update to the last emission of the library. @@ -571,8 +572,11 @@ class LibraryPresenter( private fun getGroupedMangaItems(libraryManga: List): Pair> { val grouping: MutableList> = mutableListOf() when (groupType) { - LibraryGroup.BY_STATUS -> libraryManga.distinctBy { it.manga.status }.map { it.manga.status }.forEachIndexed { index, status -> - grouping += Triple(status.toString(), index, mapStatus(status)) + LibraryGroup.BY_STATUS -> { + grouping += Triple(SManga.ONGOING.toString(), SManga.ONGOING, context.getString(R.string.ongoing)) + grouping += Triple(SManga.LICENSED.toString(), SManga.LICENSED, context.getString(R.string.licensed)) + grouping += Triple(SManga.COMPLETED.toString(), SManga.COMPLETED, context.getString(R.string.completed)) + grouping += Triple(SManga.UNKNOWN.toString(), SManga.UNKNOWN, context.getString(R.string.unknown)) } LibraryGroup.BY_SOURCE -> libraryManga.distinctBy { it.manga.source }.map { it.manga.source }.forEachIndexed { index, sourceLong -> grouping += Triple(sourceLong.toString(), index, sourceManager.getOrStub(sourceLong).name) @@ -604,7 +608,7 @@ class LibraryPresenter( "not tracked" } }() - val group = grouping.find { it.first == mapTrackingOrder(status) } + val group = grouping.find { it.first == trackManager.mapTrackingOrder(status, context).toString() } if (group != null) { map[group.second]?.plusAssign(libraryItem) ?: map.put(group.second, mutableListOf(libraryItem)) } else { @@ -621,7 +625,7 @@ class LibraryPresenter( } } else -> { - val group = grouping.find { it.first == libraryItem.manga.status.toString() } + val group = grouping.find { it.second == libraryItem.manga.status } if (group != null) { map[group.second]?.plusAssign(libraryItem) ?: map.put(group.second, mutableListOf(libraryItem)) } else { @@ -635,7 +639,7 @@ class LibraryPresenter( val categories = ( when (groupType) { LibraryGroup.BY_SOURCE -> grouping.sortedBy { it.third.toLowerCase() } - LibraryGroup.BY_TRACK_STATUS -> grouping.filter { it.second in map.keys } + LibraryGroup.BY_TRACK_STATUS, LibraryGroup.BY_STATUS -> grouping.filter { it.second in map.keys } else -> grouping } ).map { @@ -646,30 +650,5 @@ class LibraryPresenter( return map to categories } - - private fun mapTrackingOrder(status: String): String { - with(context) { - return when (status) { - getString(R.string.reading), getString(R.string.currently_reading) -> "1" - getString(R.string.repeating) -> "2" - getString(R.string.plan_to_read), getString(R.string.want_to_read) -> "3" - getString(R.string.on_hold), getString(R.string.paused) -> "4" - getString(R.string.completed) -> "5" - getString(R.string.dropped) -> "6" - else -> "7" - } - } - } - - private fun mapStatus(status: Int): String { - return context.getString( - when (status) { - SManga.LICENSED -> R.string.licensed - SManga.ONGOING -> R.string.ongoing - SManga.COMPLETED -> R.string.completed - else -> R.string.unknown - } - ) - } // SY <-- } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt index e4ada082a..ba4aa755f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt @@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.library.LibraryUpdateJob import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys +import eu.kanade.tachiyomi.data.preference.PreferenceValues import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.asImmediateFlow import eu.kanade.tachiyomi.ui.base.controller.DialogController @@ -21,6 +22,7 @@ import eu.kanade.tachiyomi.ui.library.LibrarySettingsSheet import eu.kanade.tachiyomi.util.preference.defaultValue import eu.kanade.tachiyomi.util.preference.entriesRes import eu.kanade.tachiyomi.util.preference.intListPreference +import eu.kanade.tachiyomi.util.preference.listPreference import eu.kanade.tachiyomi.util.preference.multiSelectListPreference import eu.kanade.tachiyomi.util.preference.onChange import eu.kanade.tachiyomi.util.preference.onClick @@ -194,6 +196,24 @@ class SettingsLibraryController : SettingsController() { } .launchIn(scope) } + // SY --> + listPreference { + key = Keys.groupLibraryUpdateType + titleRes = R.string.library_group_updates + entriesRes = arrayOf( + R.string.library_group_updates_global, + R.string.library_group_updates_all_but_ungrouped, + R.string.library_group_updates_all + ) + entryValues = arrayOf( + PreferenceValues.GroupLibraryMode.GLOBAL.name, + PreferenceValues.GroupLibraryMode.ALL_BUT_UNGROUPED.name, + PreferenceValues.GroupLibraryMode.ALL.name + ) + defaultValue = PreferenceValues.GroupLibraryMode.GLOBAL.name + summary = "%s" + } + // SY <-- intListPreference { key = Keys.libraryUpdatePrioritization titleRes = R.string.pref_library_update_prioritization diff --git a/app/src/main/res/values/strings_sy.xml b/app/src/main/res/values/strings_sy.xml index a803b3161..37fe6ae0e 100644 --- a/app/src/main/res/values/strings_sy.xml +++ b/app/src/main/res/values/strings_sy.xml @@ -152,6 +152,10 @@ Use last saved pre-migration preferences and sources to mass migrate Library settings sheet More library display settings + Library dynamic category updates + Always launch global updates + Launch global updates only for ungrouped, category updates for others + Launch category updates all the time Download threads