Add dynamic category library update upgrades
This commit is contained in:
parent
20aa5b9aa1
commit
9e0e2db25d
@ -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<LibraryManga> {
|
||||
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 }
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -46,4 +46,12 @@ object PreferenceValues {
|
||||
PARTIAL,
|
||||
BLOCKED
|
||||
}
|
||||
|
||||
// SY -->
|
||||
enum class GroupLibraryMode {
|
||||
GLOBAL,
|
||||
ALL_BUT_UNGROUPED,
|
||||
ALL
|
||||
}
|
||||
// SY <--
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 <--
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<LibraryController>() {
|
||||
|
||||
@ -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<TrackManager>().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<LibraryItem>): Pair<LibraryMap, List<Category>> {
|
||||
val grouping: MutableList<Triple<String, Int, String>> = 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 <--
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -152,6 +152,10 @@
|
||||
<string name="pref_skip_pre_migration_summary">Use last saved pre-migration preferences and sources to mass migrate</string>
|
||||
<string name="library_settings_sheet">Library settings sheet</string>
|
||||
<string name="library_settings_sheet_summary">More library display settings</string>
|
||||
<string name="library_group_updates">Library dynamic category updates</string>
|
||||
<string name="library_group_updates_global">Always launch global updates</string>
|
||||
<string name="library_group_updates_all_but_ungrouped">Launch global updates only for ungrouped, category updates for others</string>
|
||||
<string name="library_group_updates_all">Launch category updates all the time</string>
|
||||
|
||||
<!-- Reader Settings -->
|
||||
<string name="download_threads">Download threads</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user