Auto sync read chapters from Trackers & mark read to update (#28)
* Mark chapter(s) as read will update Tracking * Fix: sync tracking 2 ways for all trackers * automatically sync read chapters from Trackers
This commit is contained in:
parent
81376ae818
commit
ce7177efc6
7 changed files with 98 additions and 12 deletions
|
|
@ -1,7 +1,6 @@
|
|||
package eu.kanade.domain.track.interactor
|
||||
|
||||
import eu.kanade.domain.track.model.toDbTrack
|
||||
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
||||
import eu.kanade.tachiyomi.data.track.Tracker
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.common.util.system.logcat
|
||||
|
|
@ -22,26 +21,36 @@ class SyncChapterProgressWithTrack(
|
|||
remoteTrack: Track,
|
||||
tracker: Tracker,
|
||||
) {
|
||||
if (tracker !is EnhancedTracker) {
|
||||
return
|
||||
}
|
||||
// KKM -->
|
||||
// if (tracker !is EnhancedTracker) {
|
||||
// return
|
||||
// }
|
||||
// <-- KKM
|
||||
|
||||
// Current chapters in database
|
||||
val sortedChapters = getChaptersByMangaId.await(mangaId)
|
||||
.sortedBy { it.chapterNumber }
|
||||
.filter { it.isRecognizedNumber }
|
||||
|
||||
// Chapters to update to follow tracker
|
||||
val chapterUpdates = sortedChapters
|
||||
.filter { chapter -> chapter.chapterNumber <= remoteTrack.lastChapterRead && !chapter.read }
|
||||
.map { it.copy(read = true).toChapterUpdate() }
|
||||
|
||||
// only take into account continuous reading
|
||||
val localLastRead = sortedChapters.takeWhile { it.read }.lastOrNull()?.chapterNumber ?: 0F
|
||||
// Tracker will update to latest read chapter
|
||||
val updatedTrack = remoteTrack.copy(lastChapterRead = localLastRead.toDouble())
|
||||
|
||||
try {
|
||||
tracker.update(updatedTrack.toDbTrack())
|
||||
// Update Tracker to localLastRead if needed
|
||||
if (updatedTrack.lastChapterRead > remoteTrack.lastChapterRead) {
|
||||
tracker.update(updatedTrack.toDbTrack())
|
||||
// update Track in database
|
||||
insertTrack.await(updatedTrack)
|
||||
}
|
||||
// Update local chapters following Tracker
|
||||
updateChapter.awaitAll(chapterUpdates)
|
||||
insertTrack.await(updatedTrack)
|
||||
} catch (e: Throwable) {
|
||||
logcat(LogPriority.WARN, e)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,4 +35,6 @@ class TrackPreferences(
|
|||
fun anilistScoreType() = preferenceStore.getString("anilist_score_type", Anilist.POINT_10)
|
||||
|
||||
fun autoUpdateTrack() = preferenceStore.getBoolean("pref_auto_update_manga_sync_key", true)
|
||||
fun updateTrackMarkedRead() = preferenceStore.getBoolean("pref_update_tracking_marked_read_key", false)
|
||||
fun autoSyncReadChapters() = preferenceStore.getBoolean("pref_auto_sync_read_chapters_key", false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,6 +125,14 @@ object SettingsTrackingScreen : SearchableSettings {
|
|||
pref = trackPreferences.autoUpdateTrack(),
|
||||
title = stringResource(MR.strings.pref_auto_update_manga_sync),
|
||||
),
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
pref = trackPreferences.updateTrackMarkedRead(),
|
||||
title = stringResource(MR.strings.pref_update_tracking_marked_read),
|
||||
),
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
pref = trackPreferences.autoSyncReadChapters(),
|
||||
title = stringResource(MR.strings.pref_auto_sync_read_chapters),
|
||||
),
|
||||
Preference.PreferenceGroup(
|
||||
title = stringResource(MR.strings.services),
|
||||
preferenceItems = persistentListOf(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package eu.kanade.tachiyomi.ui.manga
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.SnackbarResult
|
||||
|
|
@ -29,7 +30,10 @@ import eu.kanade.domain.manga.model.toDomainManga
|
|||
import eu.kanade.domain.manga.model.toSManga
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.domain.track.interactor.AddTracks
|
||||
import eu.kanade.domain.track.interactor.RefreshTracks
|
||||
import eu.kanade.domain.track.interactor.TrackChapter
|
||||
import eu.kanade.domain.track.model.toDomainTrack
|
||||
import eu.kanade.domain.track.service.TrackPreferences
|
||||
import eu.kanade.domain.ui.UiPreferences
|
||||
import eu.kanade.presentation.manga.DownloadAction
|
||||
import eu.kanade.presentation.manga.components.ChapterDownloadAction
|
||||
|
|
@ -55,6 +59,7 @@ import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
|||
import eu.kanade.tachiyomi.util.chapter.getNextUnread
|
||||
import eu.kanade.tachiyomi.util.removeCovers
|
||||
import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import exh.debug.DebugToggles
|
||||
import exh.eh.EHentaiUpdateHelper
|
||||
import exh.log.xLogD
|
||||
|
|
@ -156,6 +161,10 @@ class MangaScreenModel(
|
|||
private val libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||
readerPreferences: ReaderPreferences = Injekt.get(),
|
||||
uiPreferences: UiPreferences = Injekt.get(),
|
||||
// KMK -->
|
||||
private val trackPreferences: TrackPreferences = Injekt.get(),
|
||||
private val trackChapter: TrackChapter = Injekt.get(),
|
||||
// KMK <--
|
||||
private val trackerManager: TrackerManager = Injekt.get(),
|
||||
private val downloadManager: DownloadManager = Injekt.get(),
|
||||
private val downloadCache: DownloadCache = Injekt.get(),
|
||||
|
|
@ -450,6 +459,7 @@ class MangaScreenModel(
|
|||
}
|
||||
// KMK <--
|
||||
val fetchFromSourceTasks = listOf(
|
||||
async { syncTrackers() },
|
||||
async { if (needRefreshInfo) fetchMangaFromSource() },
|
||||
async { if (needRefreshChapter) fetchChaptersFromSource() },
|
||||
)
|
||||
|
|
@ -461,10 +471,35 @@ class MangaScreenModel(
|
|||
}
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
private suspend fun syncTrackers() {
|
||||
if (!trackPreferences.updateTrackMarkedRead().get()) return
|
||||
|
||||
val refreshTracks = Injekt.get<RefreshTracks>()
|
||||
refreshTracks.await(mangaId)
|
||||
.filter { it.first != null }
|
||||
.forEach { (track, e) ->
|
||||
logcat(LogPriority.ERROR, e) {
|
||||
"Failed to refresh track data mangaId=$mangaId for service ${track!!.id}"
|
||||
}
|
||||
withUIContext {
|
||||
context.toast(
|
||||
context.stringResource(
|
||||
MR.strings.track_error,
|
||||
track!!.name,
|
||||
e.message ?: "",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
// KMK <--
|
||||
|
||||
fun fetchAllFromSource(manualFetch: Boolean = true) {
|
||||
screenModelScope.launch {
|
||||
updateSuccessState { it.copy(isRefreshingData = true) }
|
||||
val fetchFromSourceTasks = listOf(
|
||||
async { syncTrackers() },
|
||||
async { fetchMangaFromSource(manualFetch) },
|
||||
async { fetchChaptersFromSource(manualFetch) },
|
||||
)
|
||||
|
|
@ -669,7 +704,7 @@ class MangaScreenModel(
|
|||
mergedManga = networkToLocalManga.await(mergedManga)
|
||||
|
||||
getCategories.await(originalMangaId)
|
||||
.let {
|
||||
.let { it ->
|
||||
setMangaCategories.await(mergedManga.id, it.map { it.id })
|
||||
}
|
||||
|
||||
|
|
@ -1163,6 +1198,11 @@ class MangaScreenModel(
|
|||
when (swipeAction) {
|
||||
LibraryPreferences.ChapterSwipeAction.ToggleRead -> {
|
||||
markChaptersRead(listOf(chapter), !chapter.read)
|
||||
// KMK -->
|
||||
if (!chapter.read) {
|
||||
updateTrackChapterMarkedAsRead(chapter)
|
||||
}
|
||||
// KMK <--
|
||||
}
|
||||
LibraryPreferences.ChapterSwipeAction.ToggleBookmark -> {
|
||||
bookmarkChapters(listOf(chapter), !chapter.bookmark)
|
||||
|
|
@ -1306,9 +1346,32 @@ class MangaScreenModel(
|
|||
chapters = chapters.toTypedArray(),
|
||||
)
|
||||
}
|
||||
// KMK -->
|
||||
if (read) {
|
||||
chapters.maxByOrNull { it.chapterNumber }
|
||||
?.also { updateTrackChapterMarkedAsRead(it) }
|
||||
}
|
||||
// KMK <--
|
||||
toggleAllSelection(false)
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
/**
|
||||
* Starts the service that updates the chapter marked as read in sync services. This operation
|
||||
* will run in a background thread and errors are ignored.
|
||||
*/
|
||||
private fun updateTrackChapterMarkedAsRead(chapter: Chapter) {
|
||||
if (!trackPreferences.updateTrackMarkedRead().get()) return
|
||||
|
||||
val manga = manga ?: return
|
||||
val context = Injekt.get<Application>()
|
||||
|
||||
screenModelScope.launchNonCancellable {
|
||||
trackChapter.await(context, manga.id, chapter.chapterNumber)
|
||||
}
|
||||
}
|
||||
// KMK <--
|
||||
|
||||
/**
|
||||
* Downloads the given list of chapters with the manager.
|
||||
* @param chapters the list of chapters to download.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<changelog bulletedList="true">
|
||||
<changelogversion versionName="Latest (r8894)" changeDate="May 17, 2024">
|
||||
<changelogtext>A dedicated screen for related entries, fetching directly from sources</changelogtext>
|
||||
<changelogtext>Faster loading of related entries</changelogtext>
|
||||
<changelogtext>Enable fetching related entries from site's entry page (things like "More like this", "Recommendations" etc.)</changelogtext>
|
||||
<changelogtext>[b]New[/b] A dedicated screen for related entries, fetching directly from sources</changelogtext>
|
||||
<changelogtext>[b]Improved[/b] Faster loading of related entries</changelogtext>
|
||||
<changelogtext>[b]Improved[/b] Enable fetching related entries from site's entry page (things like "More like this", "Recommendations" etc.)</changelogtext>
|
||||
<changelogtext>Improve & fix bugs of algorithm looking for related entries</changelogtext>
|
||||
<changelogtext>A peek into Preview-build's 'What's New' in About screen</changelogtext>
|
||||
<changelogtext>Update to TachiyomiSY preview-142</changelogtext>
|
||||
<changelogtext>[b]Improved[/b] Auto sync read chapters from Trackers & mark read to update</changelogtext>
|
||||
<changelogtext>[b]New[/b] A peek into Preview-build's 'What's New' in About screen</changelogtext>
|
||||
<changelogtext>[b]Update to TachiyomiSY preview-142[/b]</changelogtext>
|
||||
</changelogversion>
|
||||
<changelogversion versionName="r8852" changeDate="May 9,2024">
|
||||
<changelogtext>Beta build switch to 'preview' repo</changelogtext>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
<changelogtext>[b]Improved[/b] Faster loading of related entries</changelogtext>
|
||||
<changelogtext>[b]Improved[/b] Enable fetching related entries from site's entry page (things like "More like this", "Recommendations" etc.)</changelogtext>
|
||||
<changelogtext>Improve & fix bugs of algorithm looking for related entries</changelogtext>
|
||||
<changelogtext>[b]Improved[/b] Auto sync read chapters from Trackers & mark read to update</changelogtext>
|
||||
<changelogtext>[b]New[/b] A peek into Preview-build's 'What's New' in About screen</changelogtext>
|
||||
<changelogtext>[b]Update to TachiyomiSY 1.10.6[/b]</changelogtext>
|
||||
<changelogtext>[b]Update to Mihon 0.16.6[/b]</changelogtext>
|
||||
|
|
|
|||
|
|
@ -501,6 +501,8 @@
|
|||
<!-- Tracking section -->
|
||||
<string name="tracking_guide">Tracking guide</string>
|
||||
<string name="pref_auto_update_manga_sync">Update progress after reading</string>
|
||||
<string name="pref_update_tracking_marked_read">Update progress when marked as read</string>
|
||||
<string name="pref_auto_sync_read_chapters">Auto sync read chapters from Trackers</string>
|
||||
<string name="services">Trackers</string>
|
||||
<string name="tracking_info">One-way sync to update the chapter progress in external tracker services. Set up tracking for individual entries from their tracking button.</string>
|
||||
<string name="enhanced_services">Enhanced trackers</string>
|
||||
|
|
|
|||
Loading…
Reference in a new issue