diff --git a/app/src/main/java/eu/kanade/domain/track/interactor/SyncChapterProgressWithTrack.kt b/app/src/main/java/eu/kanade/domain/track/interactor/SyncChapterProgressWithTrack.kt index 8e6df2289..42cba51e7 100644 --- a/app/src/main/java/eu/kanade/domain/track/interactor/SyncChapterProgressWithTrack.kt +++ b/app/src/main/java/eu/kanade/domain/track/interactor/SyncChapterProgressWithTrack.kt @@ -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) } diff --git a/app/src/main/java/eu/kanade/domain/track/service/TrackPreferences.kt b/app/src/main/java/eu/kanade/domain/track/service/TrackPreferences.kt index ab000a9ea..6e58ba19d 100644 --- a/app/src/main/java/eu/kanade/domain/track/service/TrackPreferences.kt +++ b/app/src/main/java/eu/kanade/domain/track/service/TrackPreferences.kt @@ -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) } diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsTrackingScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsTrackingScreen.kt index 021f0ceb2..6ee83c59d 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsTrackingScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsTrackingScreen.kt @@ -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( diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt index 5cf589c9a..75e88aa21 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt @@ -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.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() + + 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. diff --git a/app/src/main/res/raw/changelog_debug.xml b/app/src/main/res/raw/changelog_debug.xml index 651eb1bd6..e7b360e58 100644 --- a/app/src/main/res/raw/changelog_debug.xml +++ b/app/src/main/res/raw/changelog_debug.xml @@ -1,12 +1,13 @@ - A dedicated screen for related entries, fetching directly from sources - Faster loading of related entries - Enable fetching related entries from site's entry page (things like "More like this", "Recommendations" etc.) + [b]New[/b] A dedicated screen for related entries, fetching directly from sources + [b]Improved[/b] Faster loading of related entries + [b]Improved[/b] Enable fetching related entries from site's entry page (things like "More like this", "Recommendations" etc.) Improve & fix bugs of algorithm looking for related entries - A peek into Preview-build's 'What's New' in About screen - Update to TachiyomiSY preview-142 + [b]Improved[/b] Auto sync read chapters from Trackers & mark read to update + [b]New[/b] A peek into Preview-build's 'What's New' in About screen + [b]Update to TachiyomiSY preview-142[/b] Beta build switch to 'preview' repo diff --git a/app/src/main/res/raw/changelog_release.xml b/app/src/main/res/raw/changelog_release.xml index eaa09ebdf..d7e269bfd 100644 --- a/app/src/main/res/raw/changelog_release.xml +++ b/app/src/main/res/raw/changelog_release.xml @@ -5,6 +5,7 @@ [b]Improved[/b] Faster loading of related entries [b]Improved[/b] Enable fetching related entries from site's entry page (things like "More like this", "Recommendations" etc.) Improve & fix bugs of algorithm looking for related entries + [b]Improved[/b] Auto sync read chapters from Trackers & mark read to update [b]New[/b] A peek into Preview-build's 'What's New' in About screen [b]Update to TachiyomiSY 1.10.6[/b] [b]Update to Mihon 0.16.6[/b] diff --git a/i18n/src/commonMain/resources/MR/base/strings.xml b/i18n/src/commonMain/resources/MR/base/strings.xml index 7828738b8..a48630dbe 100644 --- a/i18n/src/commonMain/resources/MR/base/strings.xml +++ b/i18n/src/commonMain/resources/MR/base/strings.xml @@ -501,6 +501,8 @@ Tracking guide Update progress after reading + Update progress when marked as read + Auto sync read chapters from Trackers Trackers One-way sync to update the chapter progress in external tracker services. Set up tracking for individual entries from their tracking button. Enhanced trackers