Parcourir la source

Move tracker binding logic to interactor

arkon il y a 1 an
Parent
commit
69223df27c

+ 1 - 1
app/src/main/java/eu/kanade/domain/DomainModule.kt

@@ -118,7 +118,7 @@ class DomainModule : InjektModule {
 
         addSingletonFactory<TrackRepository> { TrackRepositoryImpl(get()) }
         addFactory { TrackChapter(get(), get(), get(), get()) }
-        addFactory { AddTracks(get(), get(), get()) }
+        addFactory { AddTracks(get(), get(), get(), get()) }
         addFactory { RefreshTracks(get(), get(), get(), get()) }
         addFactory { DeleteTrack(get()) }
         addFactory { GetTracksPerManga(get()) }

+ 79 - 20
app/src/main/java/eu/kanade/domain/track/interactor/AddTracks.kt

@@ -1,45 +1,104 @@
 package eu.kanade.domain.track.interactor
 
+import eu.kanade.domain.track.model.toDbTrack
 import eu.kanade.domain.track.model.toDomainTrack
+import eu.kanade.tachiyomi.data.database.models.Track
 import eu.kanade.tachiyomi.data.track.EnhancedTracker
 import eu.kanade.tachiyomi.data.track.Tracker
 import eu.kanade.tachiyomi.source.Source
+import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone
 import logcat.LogPriority
+import tachiyomi.core.util.lang.withIOContext
 import tachiyomi.core.util.lang.withNonCancellableContext
 import tachiyomi.core.util.system.logcat
+import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
+import tachiyomi.domain.history.interactor.GetHistory
 import tachiyomi.domain.manga.model.Manga
 import tachiyomi.domain.track.interactor.GetTracks
 import tachiyomi.domain.track.interactor.InsertTrack
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
+import java.time.ZoneOffset
 
 class AddTracks(
     private val getTracks: GetTracks,
     private val insertTrack: InsertTrack,
     private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack,
+    private val getChaptersByMangaId: GetChaptersByMangaId,
 ) {
 
-    suspend fun bindEnhancedTracks(manga: Manga, source: Source) = withNonCancellableContext {
-        getTracks.await(manga.id)
-            .filterIsInstance<EnhancedTracker>()
-            .filter { it.accept(source) }
-            .forEach { service ->
-                try {
-                    service.match(manga)?.let { track ->
-                        track.manga_id = manga.id
-                        (service as Tracker).bind(track)
-                        insertTrack.await(track.toDomainTrack()!!)
-
-                        syncChapterProgressWithTrack.await(
-                            manga.id,
-                            track.toDomainTrack()!!,
-                            service,
+    // TODO: update all trackers based on common data
+    suspend fun bind(tracker: Tracker, item: Track, mangaId: Long) = withNonCancellableContext {
+        withIOContext {
+            val allChapters = getChaptersByMangaId.await(mangaId)
+            val hasReadChapters = allChapters.any { it.read }
+            tracker.bind(item, hasReadChapters)
+
+            var track = item.toDomainTrack(idRequired = false) ?: return@withIOContext
+
+            insertTrack.await(track)
+
+            // TODO: merge into [SyncChapterProgressWithTrack]?
+            // Update chapter progress if newer chapters marked read locally
+            if (hasReadChapters) {
+                val latestLocalReadChapterNumber = allChapters
+                    .sortedBy { it.chapterNumber }
+                    .takeWhile { it.read }
+                    .lastOrNull()
+                    ?.chapterNumber ?: -1.0
+
+                if (latestLocalReadChapterNumber > track.lastChapterRead) {
+                    track = track.copy(
+                        lastChapterRead = latestLocalReadChapterNumber,
+                    )
+                    tracker.setRemoteLastChapterRead(track.toDbTrack(), latestLocalReadChapterNumber.toInt())
+                }
+
+                if (track.startDate <= 0) {
+                    val firstReadChapterDate = Injekt.get<GetHistory>().await(mangaId)
+                        .sortedBy { it.readAt }
+                        .firstOrNull()
+                        ?.readAt
+
+                    firstReadChapterDate?.let {
+                        val startDate = firstReadChapterDate.time.convertEpochMillisZone(ZoneOffset.systemDefault(), ZoneOffset.UTC)
+                        track = track.copy(
+                            startDate = startDate,
                         )
+                        tracker.setRemoteStartDate(track.toDbTrack(), startDate)
                     }
-                } catch (e: Exception) {
-                    logcat(
-                        LogPriority.WARN,
-                        e,
-                    ) { "Could not match manga: ${manga.title} with service $service" }
                 }
             }
+
+            syncChapterProgressWithTrack.await(mangaId, track, tracker)
+        }
+    }
+
+    suspend fun bindEnhancedTrackers(manga: Manga, source: Source) = withNonCancellableContext {
+        withIOContext {
+            getTracks.await(manga.id)
+                .filterIsInstance<EnhancedTracker>()
+                .filter { it.accept(source) }
+                .forEach { service ->
+                    try {
+                        service.match(manga)?.let { track ->
+                            track.manga_id = manga.id
+                            (service as Tracker).bind(track)
+                            insertTrack.await(track.toDomainTrack()!!)
+
+                            syncChapterProgressWithTrack.await(
+                                manga.id,
+                                track.toDomainTrack()!!,
+                                service,
+                            )
+                        }
+                    } catch (e: Exception) {
+                        logcat(
+                            LogPriority.WARN,
+                            e,
+                        ) { "Could not match manga: ${manga.title} with service $service" }
+                    }
+                }
+        }
     }
 }

+ 16 - 66
app/src/main/java/eu/kanade/tachiyomi/data/track/BaseTracker.kt

@@ -2,26 +2,21 @@ package eu.kanade.tachiyomi.data.track
 
 import android.app.Application
 import androidx.annotation.CallSuper
-import eu.kanade.domain.track.interactor.SyncChapterProgressWithTrack
-import eu.kanade.domain.track.model.toDbTrack
+import eu.kanade.domain.track.interactor.AddTracks
 import eu.kanade.domain.track.model.toDomainTrack
 import eu.kanade.domain.track.service.TrackPreferences
 import eu.kanade.tachiyomi.data.database.models.Track
 import eu.kanade.tachiyomi.network.NetworkHelper
-import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone
 import eu.kanade.tachiyomi.util.system.toast
 import logcat.LogPriority
 import okhttp3.OkHttpClient
 import tachiyomi.core.util.lang.withIOContext
 import tachiyomi.core.util.lang.withUIContext
 import tachiyomi.core.util.system.logcat
-import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
-import tachiyomi.domain.history.interactor.GetHistory
 import tachiyomi.domain.track.interactor.InsertTrack
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 import uy.kohesive.injekt.injectLazy
-import java.time.ZoneOffset
 import tachiyomi.domain.track.model.Track as DomainTrack
 
 abstract class BaseTracker(
@@ -31,8 +26,8 @@ abstract class BaseTracker(
 
     val trackPreferences: TrackPreferences by injectLazy()
     val networkService: NetworkHelper by injectLazy()
+    private val addTracks: AddTracks by injectLazy()
     private val insertTrack: InsertTrack by injectLazy()
-    private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack by injectLazy()
 
     override val client: OkHttpClient
         get() = networkService.client
@@ -66,53 +61,10 @@ abstract class BaseTracker(
         trackPreferences.setCredentials(this, username, password)
     }
 
-    // TODO: move this to an interactor, and update all trackers based on common data
     override suspend fun register(item: Track, mangaId: Long) {
         item.manga_id = mangaId
         try {
-            withIOContext {
-                val allChapters = Injekt.get<GetChaptersByMangaId>().await(mangaId)
-                val hasReadChapters = allChapters.any { it.read }
-                bind(item, hasReadChapters)
-
-                var track = item.toDomainTrack(idRequired = false) ?: return@withIOContext
-
-                insertTrack.await(track)
-
-                // TODO: merge into [SyncChapterProgressWithTrack]?
-                // Update chapter progress if newer chapters marked read locally
-                if (hasReadChapters) {
-                    val latestLocalReadChapterNumber = allChapters
-                        .sortedBy { it.chapterNumber }
-                        .takeWhile { it.read }
-                        .lastOrNull()
-                        ?.chapterNumber ?: -1.0
-
-                    if (latestLocalReadChapterNumber > track.lastChapterRead) {
-                        track = track.copy(
-                            lastChapterRead = latestLocalReadChapterNumber,
-                        )
-                        setRemoteLastChapterRead(track.toDbTrack(), latestLocalReadChapterNumber.toInt())
-                    }
-
-                    if (track.startDate <= 0) {
-                        val firstReadChapterDate = Injekt.get<GetHistory>().await(mangaId)
-                            .sortedBy { it.readAt }
-                            .firstOrNull()
-                            ?.readAt
-
-                        firstReadChapterDate?.let {
-                            val startDate = firstReadChapterDate.time.convertEpochMillisZone(ZoneOffset.systemDefault(), ZoneOffset.UTC)
-                            track = track.copy(
-                                startDate = startDate,
-                            )
-                            setRemoteStartDate(track.toDbTrack(), startDate)
-                        }
-                    }
-                }
-
-                syncChapterProgressWithTrack.await(mangaId, track, this@BaseTracker)
-            }
+            addTracks.bind(this, item, mangaId)
         } catch (e: Throwable) {
             withUIContext { Injekt.get<Application>().toast(e.message) }
         }
@@ -123,7 +75,7 @@ abstract class BaseTracker(
         if (track.status == getCompletionStatus() && track.total_chapters != 0) {
             track.last_chapter_read = track.total_chapters.toFloat()
         }
-        withIOContext { updateRemote(track) }
+        updateRemote(track)
     }
 
     override suspend fun setRemoteLastChapterRead(track: Track, chapterNumber: Int) {
@@ -135,35 +87,33 @@ abstract class BaseTracker(
             track.status = getCompletionStatus()
             track.finished_reading_date = System.currentTimeMillis()
         }
-        withIOContext { updateRemote(track) }
+        updateRemote(track)
     }
 
     override suspend fun setRemoteScore(track: Track, scoreString: String) {
         track.score = indexToScore(getScoreList().indexOf(scoreString))
-        withIOContext { updateRemote(track) }
+        updateRemote(track)
     }
 
     override suspend fun setRemoteStartDate(track: Track, epochMillis: Long) {
         track.started_reading_date = epochMillis
-        withIOContext { updateRemote(track) }
+        updateRemote(track)
     }
 
     override suspend fun setRemoteFinishDate(track: Track, epochMillis: Long) {
         track.finished_reading_date = epochMillis
-        withIOContext { updateRemote(track) }
+        updateRemote(track)
     }
 
-    private suspend fun updateRemote(track: Track) {
-        withIOContext {
-            try {
-                update(track)
-                track.toDomainTrack(idRequired = false)?.let {
-                    insertTrack.await(it)
-                }
-            } catch (e: Exception) {
-                logcat(LogPriority.ERROR, e) { "Failed to update remote track data id=$id" }
-                withUIContext { Injekt.get<Application>().toast(e.message) }
+    private suspend fun updateRemote(track: Track): Unit = withIOContext {
+        try {
+            update(track)
+            track.toDomainTrack(idRequired = false)?.let {
+                insertTrack.await(it)
             }
+        } catch (e: Exception) {
+            logcat(LogPriority.ERROR, e) { "Failed to update remote track data id=$id" }
+            withUIContext { Injekt.get<Application>().toast(e.message) }
         }
     }
 }

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt

@@ -233,7 +233,7 @@ class BrowseSourceScreenModel(
                 new = new.removeCovers(coverCache)
             } else {
                 setMangaDefaultChapterFlags.await(manga)
-                addTracks.bindEnhancedTracks(manga, source)
+                addTracks.bindEnhancedTrackers(manga, source)
             }
 
             updateManga.await(new.toMangaUpdate())

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt

@@ -319,7 +319,7 @@ class MangaScreenModel(
                 }
 
                 // Finally match with enhanced tracking when available
-                addTracks.bindEnhancedTracks(manga, state.source)
+                addTracks.bindEnhancedTrackers(manga, state.source)
             }
         }
     }