diff --git a/.gitignore b/.gitignore index 8f50ca758..7308c5646 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,8 @@ /acra.properties /.idea/workspace.xml .DS_Store -.idea/ +.idea/* +!.idea/icon.png *iml *.iml diff --git a/.idea/icon.png b/.idea/icon.png new file mode 100644 index 000000000..aa04e2d83 Binary files /dev/null and b/.idea/icon.png differ diff --git a/app/.idea/.gitignore b/app/.idea/.gitignore new file mode 100644 index 000000000..26d33521a --- /dev/null +++ b/app/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/app/.idea/.name b/app/.idea/.name new file mode 100644 index 000000000..06722840d --- /dev/null +++ b/app/.idea/.name @@ -0,0 +1 @@ +MangaDownloader.kt \ No newline at end of file diff --git a/app/.idea/discord.xml b/app/.idea/discord.xml new file mode 100644 index 000000000..d8e956166 --- /dev/null +++ b/app/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/.idea/gradle.xml b/app/.idea/gradle.xml new file mode 100644 index 000000000..7c7594018 --- /dev/null +++ b/app/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/.idea/misc.xml b/app/.idea/misc.xml new file mode 100644 index 000000000..6dc906734 --- /dev/null +++ b/app/.idea/misc.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/.idea/vcs.xml b/app/.idea/vcs.xml new file mode 100644 index 000000000..6c0b86358 --- /dev/null +++ b/app/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/baseline-prof.txt b/app/src/main/baseline-prof.txt index 008c9beb9..fb83cb729 100644 --- a/app/src/main/baseline-prof.txt +++ b/app/src/main/baseline-prof.txt @@ -19976,8 +19976,8 @@ HSPLeu/kanade/domain/track/service/TrackPreferences;->(Ltachiyomi/core/pre PLeu/kanade/domain/track/service/TrackPreferences;->(Ltachiyomi/core/preference/PreferenceStore;)V HSPLeu/kanade/domain/track/service/TrackPreferences;->anilistScoreType()Ltachiyomi/core/preference/Preference; PLeu/kanade/domain/track/service/TrackPreferences;->anilistScoreType()Ltachiyomi/core/preference/Preference; -HSPLeu/kanade/domain/track/service/TrackPreferences;->trackUsername(Leu/kanade/tachiyomi/data/track/TrackService;)Ltachiyomi/core/preference/Preference; -PLeu/kanade/domain/track/service/TrackPreferences;->trackUsername(Leu/kanade/tachiyomi/data/track/TrackService;)Ltachiyomi/core/preference/Preference; +HSPLeu/kanade/domain/track/service/TrackPreferences;->trackUsername(Leu/kanade/tachiyomi/data/track/Tracker;)Ltachiyomi/core/preference/Preference; +PLeu/kanade/domain/track/service/TrackPreferences;->trackUsername(Leu/kanade/tachiyomi/data/track/Tracker;)Ltachiyomi/core/preference/Preference; Leu/kanade/domain/track/service/TrackPreferences$Companion; HSPLeu/kanade/domain/track/service/TrackPreferences$Companion;->()V PLeu/kanade/domain/track/service/TrackPreferences$Companion;->()V @@ -21563,31 +21563,31 @@ PLeu/kanade/tachiyomi/data/notification/Notifications$createChannels$9;->invoke( Leu/kanade/tachiyomi/data/saver/ImageSaver; Leu/kanade/tachiyomi/data/track/DeletableTrackService; Leu/kanade/tachiyomi/data/track/EnhancedTrackService; -Leu/kanade/tachiyomi/data/track/TrackManager; -HSPLeu/kanade/tachiyomi/data/track/TrackManager;->()V -PLeu/kanade/tachiyomi/data/track/TrackManager;->()V -HSPLeu/kanade/tachiyomi/data/track/TrackManager;->(Landroid/app/Application;)V -PLeu/kanade/tachiyomi/data/track/TrackManager;->(Landroid/app/Application;)V -HSPLeu/kanade/tachiyomi/data/track/TrackManager;->getServices()Ljava/util/List; -PLeu/kanade/tachiyomi/data/track/TrackManager;->getServices()Ljava/util/List; +Leu/kanade/tachiyomi/data/track/TrackerManager; +HSPLeu/kanade/tachiyomi/data/track/TrackerManager;->()V +PLeu/kanade/tachiyomi/data/track/TrackerManager;->()V +HSPLeu/kanade/tachiyomi/data/track/TrackerManager;->(Landroid/app/Application;)V +PLeu/kanade/tachiyomi/data/track/TrackerManager;->(Landroid/app/Application;)V +HSPLeu/kanade/tachiyomi/data/track/TrackerManager;->getServices()Ljava/util/List; +PLeu/kanade/tachiyomi/data/track/TrackerManager;->getServices()Ljava/util/List; Leu/kanade/tachiyomi/data/track/TrackManager$Companion; HSPLeu/kanade/tachiyomi/data/track/TrackManager$Companion;->()V PLeu/kanade/tachiyomi/data/track/TrackManager$Companion;->()V HSPLeu/kanade/tachiyomi/data/track/TrackManager$Companion;->(I)V PLeu/kanade/tachiyomi/data/track/TrackManager$Companion;->(I)V -Leu/kanade/tachiyomi/data/track/TrackService; -HSPLeu/kanade/tachiyomi/data/track/TrackService;->(J)V -PLeu/kanade/tachiyomi/data/track/TrackService;->(J)V -HSPLeu/kanade/tachiyomi/data/track/TrackService;->getId()J -PLeu/kanade/tachiyomi/data/track/TrackService;->getId()J -HSPLeu/kanade/tachiyomi/data/track/TrackService;->getNetworkService()Leu/kanade/tachiyomi/network/NetworkHelper; -PLeu/kanade/tachiyomi/data/track/TrackService;->getNetworkService()Leu/kanade/tachiyomi/network/NetworkHelper; -HSPLeu/kanade/tachiyomi/data/track/TrackService;->getTrackPreferences()Leu/kanade/domain/track/service/TrackPreferences; -PLeu/kanade/tachiyomi/data/track/TrackService;->getTrackPreferences()Leu/kanade/domain/track/service/TrackPreferences; -HSPLeu/kanade/tachiyomi/data/track/TrackService;->getUsername()Ljava/lang/String; -PLeu/kanade/tachiyomi/data/track/TrackService;->getUsername()Ljava/lang/String; -HSPLeu/kanade/tachiyomi/data/track/TrackService;->isLogged()Z -PLeu/kanade/tachiyomi/data/track/TrackService;->isLogged()Z +Leu/kanade/tachiyomi/data/track/Tracker; +HSPLeu/kanade/tachiyomi/data/track/Tracker;->(J)V +PLeu/kanade/tachiyomi/data/track/Tracker;->(J)V +HSPLeu/kanade/tachiyomi/data/track/Tracker;->getId()J +PLeu/kanade/tachiyomi/data/track/Tracker;->getId()J +HSPLeu/kanade/tachiyomi/data/track/Tracker;->getNetworkService()Leu/kanade/tachiyomi/network/NetworkHelper; +PLeu/kanade/tachiyomi/data/track/Tracker;->getNetworkService()Leu/kanade/tachiyomi/network/NetworkHelper; +HSPLeu/kanade/tachiyomi/data/track/Tracker;->getTrackPreferences()Leu/kanade/domain/track/service/TrackPreferences; +PLeu/kanade/tachiyomi/data/track/Tracker;->getTrackPreferences()Leu/kanade/domain/track/service/TrackPreferences; +HSPLeu/kanade/tachiyomi/data/track/Tracker;->getUsername()Ljava/lang/String; +PLeu/kanade/tachiyomi/data/track/Tracker;->getUsername()Ljava/lang/String; +HSPLeu/kanade/tachiyomi/data/track/Tracker;->isLogged()Z +PLeu/kanade/tachiyomi/data/track/Tracker;->isLogged()Z Leu/kanade/tachiyomi/data/track/TrackService$special$$inlined$injectLazy$1; HSPLeu/kanade/tachiyomi/data/track/TrackService$special$$inlined$injectLazy$1;->()V PLeu/kanade/tachiyomi/data/track/TrackService$special$$inlined$injectLazy$1;->()V diff --git a/app/src/main/java/eu/kanade/domain/DomainModule.kt b/app/src/main/java/eu/kanade/domain/DomainModule.kt index d9e02fd31..2f1863b6e 100644 --- a/app/src/main/java/eu/kanade/domain/DomainModule.kt +++ b/app/src/main/java/eu/kanade/domain/DomainModule.kt @@ -13,10 +13,8 @@ import eu.kanade.domain.extension.manga.interactor.GetExtensionSources import eu.kanade.domain.extension.manga.interactor.GetMangaExtensionLanguages import eu.kanade.domain.extension.manga.interactor.GetMangaExtensionsByType import eu.kanade.domain.items.chapter.interactor.SetReadStatus -import eu.kanade.domain.items.chapter.interactor.SyncChapterProgressWithTrack import eu.kanade.domain.items.chapter.interactor.SyncChaptersWithSource import eu.kanade.domain.items.episode.interactor.SetSeenStatus -import eu.kanade.domain.items.episode.interactor.SyncEpisodeProgressWithTrack import eu.kanade.domain.items.episode.interactor.SyncEpisodesWithSource import eu.kanade.domain.source.anime.interactor.GetAnimeSourcesWithFavoriteCount import eu.kanade.domain.source.anime.interactor.GetEnabledAnimeSources @@ -30,9 +28,13 @@ import eu.kanade.domain.source.manga.interactor.ToggleMangaSource import eu.kanade.domain.source.manga.interactor.ToggleMangaSourcePin import eu.kanade.domain.source.service.SetMigrateSorting import eu.kanade.domain.source.service.ToggleLanguage +import eu.kanade.domain.track.anime.interactor.AddAnimeTracks import eu.kanade.domain.track.anime.interactor.RefreshAnimeTracks +import eu.kanade.domain.track.anime.interactor.SyncEpisodeProgressWithTrack import eu.kanade.domain.track.anime.interactor.TrackEpisode +import eu.kanade.domain.track.manga.interactor.AddMangaTracks import eu.kanade.domain.track.manga.interactor.RefreshMangaTracks +import eu.kanade.domain.track.manga.interactor.SyncChapterProgressWithTrack import eu.kanade.domain.track.manga.interactor.TrackChapter import tachiyomi.data.category.anime.AnimeCategoryRepositoryImpl import tachiyomi.data.category.manga.MangaCategoryRepositoryImpl @@ -222,19 +224,23 @@ class DomainModule : InjektModule { addSingletonFactory { AnimeTrackRepositoryImpl(get()) } addFactory { TrackEpisode(get(), get(), get(), get()) } + addFactory { AddAnimeTracks(get(), get(), get()) } addFactory { RefreshAnimeTracks(get(), get(), get(), get()) } addFactory { DeleteAnimeTrack(get()) } addFactory { GetTracksPerAnime(get()) } addFactory { GetAnimeTracks(get()) } addFactory { InsertAnimeTrack(get()) } + addFactory { SyncEpisodeProgressWithTrack(get(), get(), get()) } addSingletonFactory { MangaTrackRepositoryImpl(get()) } addFactory { TrackChapter(get(), get(), get(), get()) } + addFactory { AddMangaTracks(get(), get(), get()) } addFactory { RefreshMangaTracks(get(), get(), get(), get()) } addFactory { DeleteMangaTrack(get()) } addFactory { GetTracksPerManga(get()) } addFactory { GetMangaTracks(get()) } addFactory { InsertMangaTrack(get()) } + addFactory { SyncChapterProgressWithTrack(get(), get(), get()) } addSingletonFactory { EpisodeRepositoryImpl(get()) } addFactory { GetEpisode(get()) } @@ -243,7 +249,6 @@ class DomainModule : InjektModule { addFactory { SetSeenStatus(get(), get(), get(), get()) } addFactory { ShouldUpdateDbEpisode() } addFactory { SyncEpisodesWithSource(get(), get(), get(), get(), get(), get(), get()) } - addFactory { SyncEpisodeProgressWithTrack(get(), get(), get()) } addSingletonFactory { ChapterRepositoryImpl(get()) } addFactory { GetChapter(get()) } @@ -252,7 +257,6 @@ class DomainModule : InjektModule { addFactory { SetReadStatus(get(), get(), get(), get()) } addFactory { ShouldUpdateDbChapter() } addFactory { SyncChaptersWithSource(get(), get(), get(), get(), get(), get(), get()) } - addFactory { SyncChapterProgressWithTrack(get(), get(), get()) } addSingletonFactory { AnimeHistoryRepositoryImpl(get()) } addFactory { GetAnimeHistory(get()) } diff --git a/app/src/main/java/eu/kanade/domain/track/anime/interactor/AddAnimeTracks.kt b/app/src/main/java/eu/kanade/domain/track/anime/interactor/AddAnimeTracks.kt new file mode 100644 index 000000000..424ce9ec0 --- /dev/null +++ b/app/src/main/java/eu/kanade/domain/track/anime/interactor/AddAnimeTracks.kt @@ -0,0 +1,47 @@ +package eu.kanade.domain.track.anime.interactor + +import eu.kanade.domain.track.anime.model.toDomainTrack +import eu.kanade.tachiyomi.animesource.AnimeSource +import eu.kanade.tachiyomi.data.track.EnhancedAnimeTracker +import eu.kanade.tachiyomi.data.track.Tracker +import logcat.LogPriority +import tachiyomi.core.util.lang.withNonCancellableContext +import tachiyomi.core.util.system.logcat +import tachiyomi.domain.entries.anime.model.Anime +import tachiyomi.domain.track.anime.interactor.GetAnimeTracks +import tachiyomi.domain.track.anime.interactor.InsertAnimeTrack + +class AddAnimeTracks( + private val getTracks: GetAnimeTracks, + private val insertTrack: InsertAnimeTrack, + private val syncChapterProgressWithTrack: SyncEpisodeProgressWithTrack, +) { + + suspend fun bindEnhancedTracks(anime: Anime, source: AnimeSource) { + withNonCancellableContext { + getTracks.await(anime.id) + .filterIsInstance() + .filter { it.accept(source) } + .forEach { service -> + try { + service.match(anime)?.let { track -> + track.anime_id = anime.id + (service as Tracker).animeService.bind(track) + insertTrack.await(track.toDomainTrack()!!) + + syncChapterProgressWithTrack.await( + anime.id, + track.toDomainTrack()!!, + service.animeService, + ) + } + } catch (e: Exception) { + logcat( + LogPriority.WARN, + e, + ) { "Could not match manga: ${anime.title} with service $service" } + } + } + } + } +} diff --git a/app/src/main/java/eu/kanade/domain/track/anime/interactor/RefreshAnimeTracks.kt b/app/src/main/java/eu/kanade/domain/track/anime/interactor/RefreshAnimeTracks.kt index c0e79ba9b..99718995b 100644 --- a/app/src/main/java/eu/kanade/domain/track/anime/interactor/RefreshAnimeTracks.kt +++ b/app/src/main/java/eu/kanade/domain/track/anime/interactor/RefreshAnimeTracks.kt @@ -1,10 +1,9 @@ package eu.kanade.domain.track.anime.interactor -import eu.kanade.domain.items.episode.interactor.SyncEpisodeProgressWithTrack import eu.kanade.domain.track.anime.model.toDbTrack import eu.kanade.domain.track.anime.model.toDomainTrack -import eu.kanade.tachiyomi.data.track.TrackManager -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.Tracker +import eu.kanade.tachiyomi.data.track.TrackerManager import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.supervisorScope @@ -13,7 +12,7 @@ import tachiyomi.domain.track.anime.interactor.InsertAnimeTrack class RefreshAnimeTracks( private val getTracks: GetAnimeTracks, - private val trackManager: TrackManager, + private val trackerManager: TrackerManager, private val insertTrack: InsertAnimeTrack, private val syncEpisodeProgressWithTrack: SyncEpisodeProgressWithTrack, ) { @@ -23,22 +22,17 @@ class RefreshAnimeTracks( * * @return Failed updates. */ - suspend fun await(animeId: Long): List> { + suspend fun await(animeId: Long): List> { return supervisorScope { return@supervisorScope getTracks.await(animeId) - .map { track -> + .map { it to trackerManager.get(it.syncId) } + .filter { (_, service) -> service?.isLoggedIn == true } + .map { (track, service) -> async { - val service = trackManager.getService(track.syncId) return@async try { - if (service?.isLoggedIn == true) { - val updatedTrack = service.animeService.refresh(track.toDbTrack()) - insertTrack.await(updatedTrack.toDomainTrack()!!) - syncEpisodeProgressWithTrack.await( - animeId, - track, - service.animeService, - ) - } + val updatedTrack = service!!.animeService.refresh(track.toDbTrack()) + insertTrack.await(updatedTrack.toDomainTrack()!!) + syncEpisodeProgressWithTrack.await(animeId, track, service.animeService) null } catch (e: Throwable) { service to e diff --git a/app/src/main/java/eu/kanade/domain/items/episode/interactor/SyncEpisodeProgressWithTrack.kt b/app/src/main/java/eu/kanade/domain/track/anime/interactor/SyncEpisodeProgressWithTrack.kt similarity index 84% rename from app/src/main/java/eu/kanade/domain/items/episode/interactor/SyncEpisodeProgressWithTrack.kt rename to app/src/main/java/eu/kanade/domain/track/anime/interactor/SyncEpisodeProgressWithTrack.kt index 2f0cde95a..c8b9c6189 100644 --- a/app/src/main/java/eu/kanade/domain/items/episode/interactor/SyncEpisodeProgressWithTrack.kt +++ b/app/src/main/java/eu/kanade/domain/track/anime/interactor/SyncEpisodeProgressWithTrack.kt @@ -1,8 +1,8 @@ -package eu.kanade.domain.items.episode.interactor +package eu.kanade.domain.track.anime.interactor import eu.kanade.domain.track.anime.model.toDbTrack -import eu.kanade.tachiyomi.data.track.AnimeTrackService -import eu.kanade.tachiyomi.data.track.EnhancedAnimeTrackService +import eu.kanade.tachiyomi.data.track.AnimeTracker +import eu.kanade.tachiyomi.data.track.EnhancedAnimeTracker import logcat.LogPriority import tachiyomi.core.util.system.logcat import tachiyomi.domain.items.episode.interactor.GetEpisodeByAnimeId @@ -10,7 +10,6 @@ import tachiyomi.domain.items.episode.interactor.UpdateEpisode import tachiyomi.domain.items.episode.model.toEpisodeUpdate import tachiyomi.domain.track.anime.interactor.InsertAnimeTrack import tachiyomi.domain.track.anime.model.AnimeTrack -import uy.kohesive.injekt.api.get class SyncEpisodeProgressWithTrack( private val updateEpisode: UpdateEpisode, @@ -21,9 +20,9 @@ class SyncEpisodeProgressWithTrack( suspend fun await( animeId: Long, remoteTrack: AnimeTrack, - service: AnimeTrackService, + service: AnimeTracker, ) { - if (service !is EnhancedAnimeTrackService) { + if (service !is EnhancedAnimeTracker) { return } diff --git a/app/src/main/java/eu/kanade/domain/track/anime/interactor/TrackEpisode.kt b/app/src/main/java/eu/kanade/domain/track/anime/interactor/TrackEpisode.kt index 86d854796..e50703b67 100644 --- a/app/src/main/java/eu/kanade/domain/track/anime/interactor/TrackEpisode.kt +++ b/app/src/main/java/eu/kanade/domain/track/anime/interactor/TrackEpisode.kt @@ -4,7 +4,7 @@ import android.content.Context import eu.kanade.domain.track.anime.model.toDbTrack import eu.kanade.domain.track.anime.service.DelayedAnimeTrackingUpdateJob import eu.kanade.domain.track.anime.store.DelayedAnimeTrackingStore -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.util.system.isOnline import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -17,7 +17,7 @@ import tachiyomi.domain.track.anime.interactor.InsertAnimeTrack class TrackEpisode( private val getTracks: GetAnimeTracks, - private val trackManager: TrackManager, + private val trackerManager: TrackerManager, private val insertTrack: InsertAnimeTrack, private val delayedTrackingStore: DelayedAnimeTrackingStore, ) { @@ -29,14 +29,14 @@ class TrackEpisode( if (tracks.isEmpty()) return@launchNonCancellable tracks.mapNotNull { track -> - val service = trackManager.getService(track.syncId) - if (service != null && service.isLoggedIn && episodeNumber > track.lastEpisodeSeen) { + val tracker = trackerManager.get(track.syncId) + if (tracker != null && tracker.isLoggedIn && episodeNumber > track.lastEpisodeSeen) { val updatedTrack = track.copy(lastEpisodeSeen = episodeNumber) async { runCatching { if (context.isOnline()) { - service.animeService.update(updatedTrack.toDbTrack(), true) + tracker.animeService.update(updatedTrack.toDbTrack(), true) insertTrack.await(updatedTrack) } else { delayedTrackingStore.addAnimeItem(updatedTrack) diff --git a/app/src/main/java/eu/kanade/domain/track/anime/service/DelayedAnimeTrackingUpdateJob.kt b/app/src/main/java/eu/kanade/domain/track/anime/service/DelayedAnimeTrackingUpdateJob.kt index 84e627330..370efec57 100644 --- a/app/src/main/java/eu/kanade/domain/track/anime/service/DelayedAnimeTrackingUpdateJob.kt +++ b/app/src/main/java/eu/kanade/domain/track/anime/service/DelayedAnimeTrackingUpdateJob.kt @@ -10,7 +10,7 @@ import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkerParameters import eu.kanade.domain.track.anime.model.toDbTrack import eu.kanade.domain.track.anime.store.DelayedAnimeTrackingStore -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.util.system.workManager import logcat.LogPriority import tachiyomi.core.util.lang.withIOContext @@ -33,7 +33,7 @@ class DelayedAnimeTrackingUpdateJob(context: Context, workerParams: WorkerParame val getTracks = Injekt.get() val insertTrack = Injekt.get() - val trackManager = Injekt.get() + val trackerManager = Injekt.get() val delayedTrackingStore = Injekt.get() withIOContext { @@ -47,10 +47,10 @@ class DelayedAnimeTrackingUpdateJob(context: Context, workerParams: WorkerParame } .forEach { animeTrack -> try { - val service = trackManager.getService(animeTrack.syncId) - if (service != null && service.isLoggedIn) { + val tracker = trackerManager.get(animeTrack.syncId) + if (tracker != null && tracker.isLoggedIn) { logcat(LogPriority.DEBUG) { "Updating delayed track item: ${animeTrack.id}, last episode seen: ${animeTrack.lastEpisodeSeen}" } - service.animeService.update(animeTrack.toDbTrack(), true) + tracker.animeService.update(animeTrack.toDbTrack(), true) insertTrack.await(animeTrack) } delayedTrackingStore.removeAnimeItem(animeTrack.id) diff --git a/app/src/main/java/eu/kanade/domain/track/manga/interactor/AddMangaTracks.kt b/app/src/main/java/eu/kanade/domain/track/manga/interactor/AddMangaTracks.kt new file mode 100644 index 000000000..d84045bce --- /dev/null +++ b/app/src/main/java/eu/kanade/domain/track/manga/interactor/AddMangaTracks.kt @@ -0,0 +1,47 @@ +package eu.kanade.domain.track.manga.interactor + +import eu.kanade.domain.track.manga.model.toDomainTrack +import eu.kanade.tachiyomi.data.track.EnhancedMangaTracker +import eu.kanade.tachiyomi.data.track.Tracker +import eu.kanade.tachiyomi.source.MangaSource +import logcat.LogPriority +import tachiyomi.core.util.lang.withNonCancellableContext +import tachiyomi.core.util.system.logcat +import tachiyomi.domain.entries.manga.model.Manga +import tachiyomi.domain.track.manga.interactor.GetMangaTracks +import tachiyomi.domain.track.manga.interactor.InsertMangaTrack + +class AddMangaTracks( + private val getTracks: GetMangaTracks, + private val insertTrack: InsertMangaTrack, + private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack, +) { + + suspend fun bindEnhancedTracks(manga: Manga, source: MangaSource) { + withNonCancellableContext { + getTracks.await(manga.id) + .filterIsInstance() + .filter { it.accept(source) } + .forEach { service -> + try { + service.match(manga)?.let { track -> + track.manga_id = manga.id + (service as Tracker).mangaService.bind(track) + insertTrack.await(track.toDomainTrack()!!) + + syncChapterProgressWithTrack.await( + manga.id, + track.toDomainTrack()!!, + service.mangaService, + ) + } + } catch (e: Exception) { + logcat( + LogPriority.WARN, + e, + ) { "Could not match manga: ${manga.title} with service $service" } + } + } + } + } +} diff --git a/app/src/main/java/eu/kanade/domain/track/manga/interactor/RefreshMangaTracks.kt b/app/src/main/java/eu/kanade/domain/track/manga/interactor/RefreshMangaTracks.kt index 4b308dc9c..56b3f8702 100644 --- a/app/src/main/java/eu/kanade/domain/track/manga/interactor/RefreshMangaTracks.kt +++ b/app/src/main/java/eu/kanade/domain/track/manga/interactor/RefreshMangaTracks.kt @@ -1,10 +1,9 @@ package eu.kanade.domain.track.manga.interactor -import eu.kanade.domain.items.chapter.interactor.SyncChapterProgressWithTrack import eu.kanade.domain.track.manga.model.toDbTrack import eu.kanade.domain.track.manga.model.toDomainTrack -import eu.kanade.tachiyomi.data.track.TrackManager -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.Tracker +import eu.kanade.tachiyomi.data.track.TrackerManager import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.supervisorScope @@ -13,7 +12,7 @@ import tachiyomi.domain.track.manga.interactor.InsertMangaTrack class RefreshMangaTracks( private val getTracks: GetMangaTracks, - private val trackManager: TrackManager, + private val trackerManager: TrackerManager, private val insertTrack: InsertMangaTrack, private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack, ) { @@ -23,22 +22,17 @@ class RefreshMangaTracks( * * @return Failed updates. */ - suspend fun await(mangaId: Long): List> { + suspend fun await(mangaId: Long): List> { return supervisorScope { return@supervisorScope getTracks.await(mangaId) - .map { track -> + .map { it to trackerManager.get(it.syncId) } + .filter { (_, service) -> service?.isLoggedIn == true } + .map { (track, service) -> async { - val service = trackManager.getService(track.syncId) return@async try { - if (service?.isLoggedIn == true) { - val updatedTrack = service.mangaService.refresh(track.toDbTrack()) - insertTrack.await(updatedTrack.toDomainTrack()!!) - syncChapterProgressWithTrack.await( - mangaId, - track, - service.mangaService, - ) - } + val updatedTrack = service!!.mangaService.refresh(track.toDbTrack()) + insertTrack.await(updatedTrack.toDomainTrack()!!) + syncChapterProgressWithTrack.await(mangaId, track, service.mangaService) null } catch (e: Throwable) { service to e diff --git a/app/src/main/java/eu/kanade/domain/items/chapter/interactor/SyncChapterProgressWithTrack.kt b/app/src/main/java/eu/kanade/domain/track/manga/interactor/SyncChapterProgressWithTrack.kt similarity index 83% rename from app/src/main/java/eu/kanade/domain/items/chapter/interactor/SyncChapterProgressWithTrack.kt rename to app/src/main/java/eu/kanade/domain/track/manga/interactor/SyncChapterProgressWithTrack.kt index afd46a8cd..86e8f03d7 100644 --- a/app/src/main/java/eu/kanade/domain/items/chapter/interactor/SyncChapterProgressWithTrack.kt +++ b/app/src/main/java/eu/kanade/domain/track/manga/interactor/SyncChapterProgressWithTrack.kt @@ -1,8 +1,8 @@ -package eu.kanade.domain.items.chapter.interactor +package eu.kanade.domain.track.manga.interactor import eu.kanade.domain.track.manga.model.toDbTrack -import eu.kanade.tachiyomi.data.track.EnhancedMangaTrackService -import eu.kanade.tachiyomi.data.track.MangaTrackService +import eu.kanade.tachiyomi.data.track.EnhancedMangaTracker +import eu.kanade.tachiyomi.data.track.MangaTracker import logcat.LogPriority import tachiyomi.core.util.system.logcat import tachiyomi.domain.items.chapter.interactor.GetChapterByMangaId @@ -20,9 +20,9 @@ class SyncChapterProgressWithTrack( suspend fun await( mangaId: Long, remoteTrack: MangaTrack, - service: MangaTrackService, + tracker: MangaTracker, ) { - if (service !is EnhancedMangaTrackService) { + if (tracker !is EnhancedMangaTracker) { return } @@ -39,7 +39,7 @@ class SyncChapterProgressWithTrack( val updatedTrack = remoteTrack.copy(lastChapterRead = localLastRead.toDouble()) try { - service.update(updatedTrack.toDbTrack()) + tracker.update(updatedTrack.toDbTrack()) updateChapter.awaitAll(chapterUpdates) insertTrack.await(updatedTrack) } catch (e: Throwable) { diff --git a/app/src/main/java/eu/kanade/domain/track/manga/interactor/TrackChapter.kt b/app/src/main/java/eu/kanade/domain/track/manga/interactor/TrackChapter.kt index c7419d327..d0c5a2a43 100644 --- a/app/src/main/java/eu/kanade/domain/track/manga/interactor/TrackChapter.kt +++ b/app/src/main/java/eu/kanade/domain/track/manga/interactor/TrackChapter.kt @@ -4,38 +4,37 @@ import android.content.Context import eu.kanade.domain.track.manga.model.toDbTrack import eu.kanade.domain.track.manga.service.DelayedMangaTrackingUpdateJob import eu.kanade.domain.track.manga.store.DelayedMangaTrackingStore -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.coroutineScope import logcat.LogPriority -import tachiyomi.core.util.lang.launchNonCancellable +import tachiyomi.core.util.lang.withNonCancellableContext import tachiyomi.core.util.system.logcat import tachiyomi.domain.track.manga.interactor.GetMangaTracks import tachiyomi.domain.track.manga.interactor.InsertMangaTrack class TrackChapter( private val getTracks: GetMangaTracks, - private val trackManager: TrackManager, + private val trackerManager: TrackerManager, private val insertTrack: InsertMangaTrack, private val delayedTrackingStore: DelayedMangaTrackingStore, ) { - suspend fun await(context: Context, mangaId: Long, chapterNumber: Double) = coroutineScope { - launchNonCancellable { + suspend fun await(context: Context, mangaId: Long, chapterNumber: Double) { + withNonCancellableContext { val tracks = getTracks.await(mangaId) - if (tracks.isEmpty()) return@launchNonCancellable + if (tracks.isEmpty()) return@withNonCancellableContext tracks.mapNotNull { track -> - val service = trackManager.getService(track.syncId) - if (service != null && service.isLoggedIn && chapterNumber > track.lastChapterRead) { + val tracker = trackerManager.get(track.syncId) + if (tracker != null && tracker.isLoggedIn && chapterNumber > track.lastChapterRead) { val updatedTrack = track.copy(lastChapterRead = chapterNumber) async { runCatching { try { - service.mangaService.update(updatedTrack.toDbTrack(), true) + tracker.mangaService.update(updatedTrack.toDbTrack(), true) insertTrack.await(updatedTrack) } catch (e: Exception) { delayedTrackingStore.addMangaItem(updatedTrack) diff --git a/app/src/main/java/eu/kanade/domain/track/manga/service/DelayedMangaTrackingUpdateJob.kt b/app/src/main/java/eu/kanade/domain/track/manga/service/DelayedMangaTrackingUpdateJob.kt index 153cd2acd..38ed2ae98 100644 --- a/app/src/main/java/eu/kanade/domain/track/manga/service/DelayedMangaTrackingUpdateJob.kt +++ b/app/src/main/java/eu/kanade/domain/track/manga/service/DelayedMangaTrackingUpdateJob.kt @@ -10,7 +10,7 @@ import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkerParameters import eu.kanade.domain.track.manga.model.toDbTrack import eu.kanade.domain.track.manga.store.DelayedMangaTrackingStore -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.util.system.workManager import logcat.LogPriority import tachiyomi.core.util.lang.withIOContext @@ -33,7 +33,7 @@ class DelayedMangaTrackingUpdateJob(context: Context, workerParams: WorkerParame val getTracks = Injekt.get() val insertTrack = Injekt.get() - val trackManager = Injekt.get() + val trackerManager = Injekt.get() val delayedTrackingStore = Injekt.get() withIOContext { @@ -47,10 +47,10 @@ class DelayedMangaTrackingUpdateJob(context: Context, workerParams: WorkerParame } .forEach { track -> try { - val service = trackManager.getService(track.syncId) - if (service != null && service.isLoggedIn) { + val tracker = trackerManager.get(track.syncId) + if (tracker != null && tracker.isLoggedIn) { logcat(LogPriority.DEBUG) { "Updating delayed track item: ${track.id}, last chapter read: ${track.lastChapterRead}" } - service.mangaService.update(track.toDbTrack(), true) + tracker.mangaService.update(track.toDbTrack(), true) insertTrack.await(track) } delayedTrackingStore.removeMangaItem(track.id) 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 06af386ea..50c93cb9d 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 @@ -1,6 +1,6 @@ package eu.kanade.domain.track.service -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.anilist.Anilist import tachiyomi.core.preference.PreferenceStore @@ -8,16 +8,16 @@ class TrackPreferences( private val preferenceStore: PreferenceStore, ) { - fun trackUsername(sync: TrackService) = preferenceStore.getString(trackUsername(sync.id), "") + fun trackUsername(sync: Tracker) = preferenceStore.getString(trackUsername(sync.id), "") - fun trackPassword(sync: TrackService) = preferenceStore.getString(trackPassword(sync.id), "") + fun trackPassword(sync: Tracker) = preferenceStore.getString(trackPassword(sync.id), "") - fun setTrackCredentials(sync: TrackService, username: String, password: String) { + fun setCredentials(sync: Tracker, username: String, password: String) { trackUsername(sync).set(username) trackPassword(sync).set(password) } - fun trackToken(sync: TrackService) = preferenceStore.getString(trackToken(sync.id), "") + fun trackToken(sync: Tracker) = preferenceStore.getString(trackToken(sync.id), "") fun anilistScoreType() = preferenceStore.getString("anilist_score_type", Anilist.POINT_10) diff --git a/app/src/main/java/eu/kanade/presentation/library/anime/AnimeLibrarySettingsDialog.kt b/app/src/main/java/eu/kanade/presentation/library/anime/AnimeLibrarySettingsDialog.kt index ff3f70a96..b623c4866 100644 --- a/app/src/main/java/eu/kanade/presentation/library/anime/AnimeLibrarySettingsDialog.kt +++ b/app/src/main/java/eu/kanade/presentation/library/anime/AnimeLibrarySettingsDialog.kt @@ -108,13 +108,13 @@ private fun ColumnScope.FilterPage( onClick = { screenModel.toggleFilter(LibraryPreferences::filterCompletedAnime) }, ) - val trackServices = remember { screenModel.trackServices } - when (trackServices.size) { + val trackers = remember { screenModel.trackers } + when (trackers.size) { 0 -> { // No trackers } 1 -> { - val service = trackServices[0] + val service = trackers[0] val filterTracker by screenModel.libraryPreferences.filterTrackedAnime( service.id.toInt(), ).collectAsState() @@ -126,7 +126,7 @@ private fun ColumnScope.FilterPage( } else -> { HeadingItem(R.string.action_filter_tracked) - trackServices.map { service -> + trackers.map { service -> val filterTracker by screenModel.libraryPreferences.filterTrackedAnime( service.id.toInt(), ).collectAsState() diff --git a/app/src/main/java/eu/kanade/presentation/library/manga/MangaLibrarySettingsDialog.kt b/app/src/main/java/eu/kanade/presentation/library/manga/MangaLibrarySettingsDialog.kt index 925ce8340..2678a45c3 100644 --- a/app/src/main/java/eu/kanade/presentation/library/manga/MangaLibrarySettingsDialog.kt +++ b/app/src/main/java/eu/kanade/presentation/library/manga/MangaLibrarySettingsDialog.kt @@ -108,13 +108,13 @@ private fun ColumnScope.FilterPage( onClick = { screenModel.toggleFilter(LibraryPreferences::filterCompletedManga) }, ) - val trackServices = remember { screenModel.trackServices } - when (trackServices.size) { + val trackers = remember { screenModel.trackers } + when (trackers.size) { 0 -> { // No trackers } 1 -> { - val service = trackServices[0] + val service = trackers[0] val filterTracker by screenModel.libraryPreferences.filterTrackedManga( service.id.toInt(), ).collectAsState() @@ -126,7 +126,7 @@ private fun ColumnScope.FilterPage( } else -> { HeadingItem(R.string.action_filter_tracked) - trackServices.map { service -> + trackers.map { service -> val filterTracker by screenModel.libraryPreferences.filterTrackedManga( service.id.toInt(), ).collectAsState() diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/Preference.kt b/app/src/main/java/eu/kanade/presentation/more/settings/Preference.kt index ef89d9933..31e1201df 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/Preference.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/Preference.kt @@ -5,7 +5,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.Tracker import tachiyomi.core.preference.Preference as PreferenceData sealed class Preference { @@ -146,10 +146,10 @@ sealed class Preference { ) : PreferenceItem() /** - * A [PreferenceItem] for individual tracking service. + * A [PreferenceItem] for individual tracker. */ - data class TrackingPreference( - val service: TrackService, + data class TrackerPreference( + val tracker: Tracker, override val title: String, val login: () -> Unit, val logout: () -> Unit, diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/PreferenceItem.kt b/app/src/main/java/eu/kanade/presentation/more/settings/PreferenceItem.kt index 52963e087..968780850 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/PreferenceItem.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/PreferenceItem.kt @@ -171,13 +171,13 @@ internal fun PreferenceItem( singleLine = false, ) } - is Preference.PreferenceItem.TrackingPreference -> { + is Preference.PreferenceItem.TrackerPreference -> { val uName by Injekt.get() - .getString(TrackPreferences.trackUsername(item.service.id)) + .getString(TrackPreferences.trackUsername(item.tracker.id)) .collectAsState() - item.service.run { + item.tracker.run { TrackingPreferenceWidget( - service = this, + tracker = this, checked = uName.isNotEmpty(), onClick = { if (isLoggedIn) item.logout() else item.login() }, ) diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt index 9f5a32883..5ef1b44dd 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt @@ -40,7 +40,7 @@ import eu.kanade.tachiyomi.data.download.anime.AnimeDownloadCache import eu.kanade.tachiyomi.data.download.manga.MangaDownloadCache import eu.kanade.tachiyomi.data.library.anime.AnimeLibraryUpdateJob import eu.kanade.tachiyomi.data.library.manga.MangaLibraryUpdateJob -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkPreferences import eu.kanade.tachiyomi.network.PREF_DOH_360 @@ -353,7 +353,7 @@ object SettingsAdvancedScreen : SearchableSettings { private fun getLibraryGroup(): Preference.PreferenceGroup { val scope = rememberCoroutineScope() val context = LocalContext.current - val trackManager = remember { Injekt.get() } + val trackerManager = remember { Injekt.get() } return Preference.PreferenceGroup( title = stringResource(R.string.label_library), @@ -374,7 +374,7 @@ object SettingsAdvancedScreen : SearchableSettings { Preference.PreferenceItem.TextPreference( title = stringResource(R.string.pref_refresh_library_tracking), subtitle = stringResource(R.string.pref_refresh_library_tracking_summary), - enabled = trackManager.hasLoggedServices(), + enabled = trackerManager.hasLoggedIn(), onClick = { MangaLibraryUpdateJob.startNow( context, diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt index c5d318333..5ff322e96 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt @@ -24,7 +24,7 @@ import eu.kanade.presentation.more.settings.widget.TriStateListDialog import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.library.anime.AnimeLibraryUpdateJob import eu.kanade.tachiyomi.data.library.manga.MangaLibraryUpdateJob -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.ui.category.CategoriesTab import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -287,7 +287,7 @@ object SettingsLibraryScreen : SearchableSettings { ), Preference.PreferenceItem.SwitchPreference( pref = libraryPreferences.autoUpdateTrackers(), - enabled = Injekt.get().hasLoggedServices(), + enabled = Injekt.get().hasLoggedIn(), title = stringResource(R.string.pref_library_update_refresh_trackers), subtitle = stringResource(R.string.pref_library_update_refresh_trackers_summary), ), diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt index 64d99511a..7008ca6d7 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt @@ -272,7 +272,7 @@ private fun getIndex() = settingScreens SettingsData( title = stringResource(screen.getTitleRes()), route = screen, - contents = screen.getPreferences(), + contents = screen.sourcePreferences(), ) } 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 faf051ae3..ce04c7efc 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 @@ -44,9 +44,9 @@ import androidx.compose.ui.unit.dp import eu.kanade.domain.track.service.TrackPreferences import eu.kanade.presentation.more.settings.Preference import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.track.EnhancedMangaTrackService -import eu.kanade.tachiyomi.data.track.TrackManager -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.EnhancedMangaTracker +import eu.kanade.tachiyomi.data.track.Tracker +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.data.track.anilist.AnilistApi import eu.kanade.tachiyomi.data.track.bangumi.BangumiApi import eu.kanade.tachiyomi.data.track.myanimelist.MyAnimeListApi @@ -83,7 +83,7 @@ object SettingsTrackingScreen : SearchableSettings { override fun getPreferences(): List { val context = LocalContext.current val trackPreferences = remember { Injekt.get() } - val trackManager = remember { Injekt.get() } + val trackerManager = remember { Injekt.get() } val sourceManager = remember { Injekt.get() } var dialog by remember { mutableStateOf(null) } @@ -91,24 +91,24 @@ object SettingsTrackingScreen : SearchableSettings { when (this) { is LoginDialog -> { TrackingLoginDialog( - service = service, + tracker = tracker, uNameStringRes = uNameStringRes, onDismissRequest = { dialog = null }, ) } is LogoutDialog -> { TrackingLogoutDialog( - service = service, + tracker = tracker, onDismissRequest = { dialog = null }, ) } } } - val enhancedMangaTrackers = trackManager.services - .filter { it is EnhancedMangaTrackService } + val enhancedMangaTrackers = trackerManager.trackers + .filter { it is EnhancedMangaTracker } .partition { service -> - val acceptedMangaSources = (service as EnhancedMangaTrackService).getAcceptedSources() + val acceptedMangaSources = (service as EnhancedMangaTracker).getAcceptedSources() sourceManager.getCatalogueSources().any { it::class.qualifiedName in acceptedMangaSources } } var enhancedMangaTrackerInfo = stringResource(R.string.enhanced_tracking_info) @@ -136,72 +136,72 @@ object SettingsTrackingScreen : SearchableSettings { Preference.PreferenceGroup( title = stringResource(R.string.services), preferenceItems = listOf( - Preference.PreferenceItem.TrackingPreference( - title = trackManager.myAnimeList.name, - service = trackManager.myAnimeList, + Preference.PreferenceItem.TrackerPreference( + title = trackerManager.myAnimeList.name, + tracker = trackerManager.myAnimeList, login = { context.openInBrowser( MyAnimeListApi.authUrl(), forceDefaultBrowser = true, ) }, - logout = { dialog = LogoutDialog(trackManager.myAnimeList) }, + logout = { dialog = LogoutDialog(trackerManager.myAnimeList) }, ), - Preference.PreferenceItem.TrackingPreference( - title = trackManager.aniList.name, - service = trackManager.aniList, + Preference.PreferenceItem.TrackerPreference( + title = trackerManager.aniList.name, + tracker = trackerManager.aniList, login = { context.openInBrowser( AnilistApi.authUrl(), forceDefaultBrowser = true, ) }, - logout = { dialog = LogoutDialog(trackManager.aniList) }, + logout = { dialog = LogoutDialog(trackerManager.aniList) }, ), - Preference.PreferenceItem.TrackingPreference( - title = trackManager.kitsu.name, - service = trackManager.kitsu, - login = { dialog = LoginDialog(trackManager.kitsu, R.string.email) }, - logout = { dialog = LogoutDialog(trackManager.kitsu) }, + Preference.PreferenceItem.TrackerPreference( + title = trackerManager.kitsu.name, + tracker = trackerManager.kitsu, + login = { dialog = LoginDialog(trackerManager.kitsu, R.string.email) }, + logout = { dialog = LogoutDialog(trackerManager.kitsu) }, ), - Preference.PreferenceItem.TrackingPreference( - title = trackManager.mangaUpdates.name, - service = trackManager.mangaUpdates, - login = { dialog = LoginDialog(trackManager.mangaUpdates, R.string.username) }, - logout = { dialog = LogoutDialog(trackManager.mangaUpdates) }, + Preference.PreferenceItem.TrackerPreference( + title = trackerManager.mangaUpdates.name, + tracker = trackerManager.mangaUpdates, + login = { dialog = LoginDialog(trackerManager.mangaUpdates, R.string.username) }, + logout = { dialog = LogoutDialog(trackerManager.mangaUpdates) }, ), - Preference.PreferenceItem.TrackingPreference( - title = trackManager.shikimori.name, - service = trackManager.shikimori, + Preference.PreferenceItem.TrackerPreference( + title = trackerManager.shikimori.name, + tracker = trackerManager.shikimori, login = { context.openInBrowser( ShikimoriApi.authUrl(), forceDefaultBrowser = true, ) }, - logout = { dialog = LogoutDialog(trackManager.shikimori) }, + logout = { dialog = LogoutDialog(trackerManager.shikimori) }, ), - Preference.PreferenceItem.TrackingPreference( - title = trackManager.simkl.name, - service = trackManager.simkl, + Preference.PreferenceItem.TrackerPreference( + title = trackerManager.simkl.name, + tracker = trackerManager.simkl, login = { context.openInBrowser( SimklApi.authUrl(), forceDefaultBrowser = true, ) }, - logout = { dialog = LogoutDialog(trackManager.simkl) }, + logout = { dialog = LogoutDialog(trackerManager.simkl) }, ), - Preference.PreferenceItem.TrackingPreference( - title = trackManager.bangumi.name, - service = trackManager.bangumi, + Preference.PreferenceItem.TrackerPreference( + title = trackerManager.bangumi.name, + tracker = trackerManager.bangumi, login = { context.openInBrowser( BangumiApi.authUrl(), forceDefaultBrowser = true, ) }, - logout = { dialog = LogoutDialog(trackManager.bangumi) }, + logout = { dialog = LogoutDialog(trackerManager.bangumi) }, ), Preference.PreferenceItem.InfoPreference(stringResource(R.string.tracking_info)), ), @@ -210,10 +210,10 @@ object SettingsTrackingScreen : SearchableSettings { title = stringResource(R.string.enhanced_services), preferenceItems = enhancedMangaTrackers.first .map { service -> - Preference.PreferenceItem.TrackingPreference( + Preference.PreferenceItem.TrackerPreference( title = service.name, - service = service, - login = { (service as EnhancedMangaTrackService).loginNoop() }, + tracker = service, + login = { (service as EnhancedMangaTracker).loginNoop() }, logout = service::logout, ) } + listOf(Preference.PreferenceItem.InfoPreference(enhancedMangaTrackerInfo)), @@ -224,15 +224,15 @@ object SettingsTrackingScreen : SearchableSettings { @Composable private fun TrackingLoginDialog( - service: TrackService, + tracker: Tracker, @StringRes uNameStringRes: Int, onDismissRequest: () -> Unit, ) { val context = LocalContext.current val scope = rememberCoroutineScope() - var username by remember { mutableStateOf(TextFieldValue(service.getUsername())) } - var password by remember { mutableStateOf(TextFieldValue(service.getPassword())) } + var username by remember { mutableStateOf(TextFieldValue(tracker.getUsername())) } + var password by remember { mutableStateOf(TextFieldValue(tracker.getPassword())) } var processing by remember { mutableStateOf(false) } var inputError by remember { mutableStateOf(false) } @@ -241,7 +241,7 @@ object SettingsTrackingScreen : SearchableSettings { title = { Row(verticalAlignment = Alignment.CenterVertically) { Text( - text = stringResource(R.string.login_title, service.name), + text = stringResource(R.string.login_title, tracker.name), modifier = Modifier.weight(1f), ) IconButton(onClick = onDismissRequest) { @@ -305,7 +305,7 @@ object SettingsTrackingScreen : SearchableSettings { processing = true val result = checkLogin( context = context, - service = service, + tracker = tracker, username = username.text, password = password.text, ) @@ -324,16 +324,16 @@ object SettingsTrackingScreen : SearchableSettings { private suspend fun checkLogin( context: Context, - service: TrackService, + tracker: Tracker, username: String, password: String, ): Boolean { return try { - service.login(username, password) + tracker.login(username, password) withUIContext { context.toast(R.string.login_success) } true } catch (e: Throwable) { - service.logout() + tracker.logout() withUIContext { context.toast(e.message.toString()) } false } @@ -341,7 +341,7 @@ object SettingsTrackingScreen : SearchableSettings { @Composable private fun TrackingLogoutDialog( - service: TrackService, + tracker: Tracker, onDismissRequest: () -> Unit, ) { val context = LocalContext.current @@ -349,7 +349,7 @@ object SettingsTrackingScreen : SearchableSettings { onDismissRequest = onDismissRequest, title = { Text( - text = stringResource(R.string.logout_title, service.name), + text = stringResource(R.string.logout_title, tracker.name), textAlign = TextAlign.Center, modifier = Modifier.fillMaxWidth(), ) @@ -365,7 +365,7 @@ object SettingsTrackingScreen : SearchableSettings { Button( modifier = Modifier.weight(1f), onClick = { - service.logout() + tracker.logout() onDismissRequest() context.toast(R.string.logout_success) }, @@ -383,10 +383,10 @@ object SettingsTrackingScreen : SearchableSettings { } private data class LoginDialog( - val service: TrackService, + val tracker: Tracker, @StringRes val uNameStringRes: Int, ) private data class LogoutDialog( - val service: TrackService, + val tracker: Tracker, ) diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/widget/TrackingPreferenceWidget.kt b/app/src/main/java/eu/kanade/presentation/more/settings/widget/TrackingPreferenceWidget.kt index e0c34fbc4..d8544d156 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/widget/TrackingPreferenceWidget.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/widget/TrackingPreferenceWidget.kt @@ -20,12 +20,12 @@ import androidx.compose.ui.unit.dp import eu.kanade.presentation.more.settings.LocalPreferenceHighlighted import eu.kanade.presentation.track.components.TrackLogoIcon import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.Tracker @Composable fun TrackingPreferenceWidget( modifier: Modifier = Modifier, - service: TrackService, + tracker: Tracker, checked: Boolean, onClick: (() -> Unit)? = null, ) { @@ -38,9 +38,9 @@ fun TrackingPreferenceWidget( .padding(horizontal = PrefsHorizontalPadding, vertical = 8.dp), verticalAlignment = Alignment.CenterVertically, ) { - TrackLogoIcon(service) + TrackLogoIcon(tracker) Text( - text = service.name, + text = tracker.name, modifier = Modifier .weight(1f) .padding(horizontal = 16.dp), diff --git a/app/src/main/java/eu/kanade/presentation/track/anime/AnimeTrackInfoDialogHome.kt b/app/src/main/java/eu/kanade/presentation/track/anime/AnimeTrackInfoDialogHome.kt index e3fdc34f0..fbb49c0a3 100644 --- a/app/src/main/java/eu/kanade/presentation/track/anime/AnimeTrackInfoDialogHome.kt +++ b/app/src/main/java/eu/kanade/presentation/track/anime/AnimeTrackInfoDialogHome.kt @@ -38,7 +38,7 @@ import eu.kanade.presentation.track.components.TrackLogoIcon import eu.kanade.presentation.track.manga.TrackDetailsItem import eu.kanade.presentation.track.manga.TrackInfoItemMenu import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.ui.entries.anime.track.AnimeTrackItem import eu.kanade.tachiyomi.util.system.copyToClipboard import java.text.DateFormat @@ -69,12 +69,12 @@ fun AnimeTrackInfoDialogHome( ) { trackItems.forEach { item -> if (item.track != null) { - val supportsScoring = item.service.animeService.getScoreList().isNotEmpty() - val supportsReadingDates = item.service.supportsReadingDates + val supportsScoring = item.tracker.animeService.getScoreList().isNotEmpty() + val supportsReadingDates = item.tracker.supportsReadingDates TrackInfoItem( title = item.track.title, - service = item.service, - status = item.service.getStatus(item.track.status.toInt()), + tracker = item.tracker, + status = item.tracker.getStatus(item.track.status.toInt()), onStatusClick = { onStatusClick(item) }, episodes = "${item.track.lastEpisodeSeen.toInt()}".let { val totalEpisodes = item.track.totalEpisodes @@ -86,7 +86,7 @@ fun AnimeTrackInfoDialogHome( } }, onEpisodesClick = { onEpisodeClick(item) }, - score = item.service.animeService.displayScore(item.track.toDbTrack()) + score = item.tracker.animeService.displayScore(item.track.toDbTrack()) .takeIf { supportsScoring && item.track.score != 0.0 }, onScoreClick = { onScoreClick(item) } .takeIf { supportsScoring }, @@ -108,7 +108,7 @@ fun AnimeTrackInfoDialogHome( ) } else { TrackInfoItemEmpty( - service = item.service, + tracker = item.tracker, onNewSearch = { onNewSearch(item) }, ) } @@ -119,7 +119,7 @@ fun AnimeTrackInfoDialogHome( @Composable private fun TrackInfoItem( title: String, - service: TrackService, + tracker: Tracker, @StringRes status: Int?, onStatusClick: () -> Unit, episodes: String, @@ -140,7 +140,7 @@ private fun TrackInfoItem( verticalAlignment = Alignment.CenterVertically, ) { TrackLogoIcon( - service = service, + tracker = tracker, onClick = onOpenInBrowser, ) Box( @@ -228,13 +228,13 @@ private fun TrackInfoItem( @Composable private fun TrackInfoItemEmpty( - service: TrackService, + tracker: Tracker, onNewSearch: () -> Unit, ) { Row( verticalAlignment = Alignment.CenterVertically, ) { - TrackLogoIcon(service) + TrackLogoIcon(tracker) TextButton( onClick = onNewSearch, modifier = Modifier diff --git a/app/src/main/java/eu/kanade/presentation/track/anime/AnimeTrackServiceSearch.kt b/app/src/main/java/eu/kanade/presentation/track/anime/AnimeTrackerSearch.kt similarity index 99% rename from app/src/main/java/eu/kanade/presentation/track/anime/AnimeTrackServiceSearch.kt rename to app/src/main/java/eu/kanade/presentation/track/anime/AnimeTrackerSearch.kt index d16787182..847dfcd66 100644 --- a/app/src/main/java/eu/kanade/presentation/track/anime/AnimeTrackServiceSearch.kt +++ b/app/src/main/java/eu/kanade/presentation/track/anime/AnimeTrackerSearch.kt @@ -53,7 +53,7 @@ import tachiyomi.presentation.core.util.plus import tachiyomi.presentation.core.util.runOnEnterKeyPressed @Composable -fun AnimeTrackServiceSearch( +fun AnimeTrackerSearch( query: TextFieldValue, onQueryChange: (TextFieldValue) -> Unit, onDispatchQuery: () -> Unit, diff --git a/app/src/main/java/eu/kanade/presentation/track/components/TrackLogoIcon.kt b/app/src/main/java/eu/kanade/presentation/track/components/TrackLogoIcon.kt index 44d98cbd2..52bf66575 100644 --- a/app/src/main/java/eu/kanade/presentation/track/components/TrackLogoIcon.kt +++ b/app/src/main/java/eu/kanade/presentation/track/components/TrackLogoIcon.kt @@ -12,12 +12,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.Tracker import tachiyomi.presentation.core.util.clickableNoIndication @Composable fun TrackLogoIcon( - service: TrackService, + tracker: Tracker, onClick: (() -> Unit)? = null, ) { val modifier = if (onClick != null) { @@ -29,13 +29,13 @@ fun TrackLogoIcon( Box( modifier = modifier .size(48.dp) - .background(color = Color(service.getLogoColor()), shape = MaterialTheme.shapes.medium) + .background(color = Color(tracker.getLogoColor()), shape = MaterialTheme.shapes.medium) .padding(4.dp), contentAlignment = Alignment.Center, ) { Image( - painter = painterResource(service.getLogo()), - contentDescription = service.name, + painter = painterResource(tracker.getLogo()), + contentDescription = tracker.name, ) } } diff --git a/app/src/main/java/eu/kanade/presentation/track/manga/MangaTrackInfoDialogHome.kt b/app/src/main/java/eu/kanade/presentation/track/manga/MangaTrackInfoDialogHome.kt index 2932cf931..5faeaaf5a 100644 --- a/app/src/main/java/eu/kanade/presentation/track/manga/MangaTrackInfoDialogHome.kt +++ b/app/src/main/java/eu/kanade/presentation/track/manga/MangaTrackInfoDialogHome.kt @@ -49,7 +49,7 @@ import eu.kanade.domain.track.manga.model.toDbTrack import eu.kanade.presentation.components.DropdownMenu import eu.kanade.presentation.track.components.TrackLogoIcon import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.ui.entries.manga.track.MangaTrackItem import eu.kanade.tachiyomi.util.system.copyToClipboard import java.text.DateFormat @@ -80,12 +80,12 @@ fun MangaTrackInfoDialogHome( ) { trackItems.forEach { item -> if (item.track != null) { - val supportsScoring = item.service.mangaService.getScoreList().isNotEmpty() - val supportsReadingDates = item.service.supportsReadingDates + val supportsScoring = item.tracker.mangaService.getScoreList().isNotEmpty() + val supportsReadingDates = item.tracker.supportsReadingDates TrackInfoItem( title = item.track.title, - service = item.service, - status = item.service.getStatus(item.track.status.toInt()), + tracker = item.tracker, + status = item.tracker.getStatus(item.track.status.toInt()), onStatusClick = { onStatusClick(item) }, chapters = "${item.track.lastChapterRead.toInt()}".let { val totalChapters = item.track.totalChapters @@ -97,7 +97,7 @@ fun MangaTrackInfoDialogHome( } }, onChaptersClick = { onChapterClick(item) }, - score = item.service.mangaService.displayScore(item.track.toDbTrack()) + score = item.tracker.mangaService.displayScore(item.track.toDbTrack()) .takeIf { supportsScoring && item.track.score != 0.0 }, onScoreClick = { onScoreClick(item) } .takeIf { supportsScoring }, @@ -119,7 +119,7 @@ fun MangaTrackInfoDialogHome( ) } else { TrackInfoItemEmpty( - service = item.service, + tracker = item.tracker, onNewSearch = { onNewSearch(item) }, ) } @@ -130,7 +130,7 @@ fun MangaTrackInfoDialogHome( @Composable private fun TrackInfoItem( title: String, - service: TrackService, + tracker: Tracker, @StringRes status: Int?, onStatusClick: () -> Unit, chapters: String, @@ -151,7 +151,7 @@ private fun TrackInfoItem( verticalAlignment = Alignment.CenterVertically, ) { TrackLogoIcon( - service = service, + tracker = tracker, onClick = onOpenInBrowser, ) Box( @@ -264,13 +264,13 @@ fun TrackDetailsItem( @Composable private fun TrackInfoItemEmpty( - service: TrackService, + tracker: Tracker, onNewSearch: () -> Unit, ) { Row( verticalAlignment = Alignment.CenterVertically, ) { - TrackLogoIcon(service) + TrackLogoIcon(tracker) TextButton( onClick = onNewSearch, modifier = Modifier diff --git a/app/src/main/java/eu/kanade/presentation/track/manga/MangaTrackServiceSearch.kt b/app/src/main/java/eu/kanade/presentation/track/manga/MangaTrackerSearch.kt similarity index 99% rename from app/src/main/java/eu/kanade/presentation/track/manga/MangaTrackServiceSearch.kt rename to app/src/main/java/eu/kanade/presentation/track/manga/MangaTrackerSearch.kt index a213017e7..e3ebc3c87 100644 --- a/app/src/main/java/eu/kanade/presentation/track/manga/MangaTrackServiceSearch.kt +++ b/app/src/main/java/eu/kanade/presentation/track/manga/MangaTrackerSearch.kt @@ -70,7 +70,7 @@ import tachiyomi.presentation.core.util.runOnEnterKeyPressed import tachiyomi.presentation.core.util.secondaryItemAlpha @Composable -fun MangaTrackServiceSearch( +fun MangaTrackerSearch( query: TextFieldValue, onQueryChange: (TextFieldValue) -> Unit, onDispatchQuery: () -> Unit, diff --git a/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt b/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt index ab9c50dba..e7a98ebe6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt @@ -29,7 +29,7 @@ import eu.kanade.tachiyomi.data.download.manga.MangaDownloadCache import eu.kanade.tachiyomi.data.download.manga.MangaDownloadManager import eu.kanade.tachiyomi.data.download.manga.MangaDownloadProvider import eu.kanade.tachiyomi.data.saver.ImageSaver -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager import eu.kanade.tachiyomi.network.JavaScriptEngine @@ -209,7 +209,7 @@ class AppModule(val app: Application) : InjektModule { addSingletonFactory { AnimeDownloadManager(app) } addSingletonFactory { AnimeDownloadCache(app) } - addSingletonFactory { TrackManager(app) } + addSingletonFactory { TrackerManager(app) } addSingletonFactory { DelayedAnimeTrackingStore(app) } addSingletonFactory { DelayedMangaTrackingStore(app) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt index aa312be3e..08db52535 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt @@ -10,7 +10,7 @@ import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.data.backup.BackupCreateJob import eu.kanade.tachiyomi.data.library.anime.AnimeLibraryUpdateJob import eu.kanade.tachiyomi.data.library.manga.MangaLibraryUpdateJob -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.network.NetworkPreferences import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE import eu.kanade.tachiyomi.ui.player.settings.PlayerPreferences @@ -50,7 +50,7 @@ object Migrations { readerPreferences: ReaderPreferences, playerPreferences: PlayerPreferences, backupPreferences: BackupPreferences, - trackManager: TrackManager, + trackerManager: TrackerManager, ): Boolean { val lastVersionCode = preferenceStore.getInt("last_version_code", 0) val oldVersion = lastVersionCode.get() @@ -164,8 +164,8 @@ object Migrations { // Force MAL log out due to login flow change // v52: switched from scraping to WebView // v53: switched from WebView to OAuth - if (trackManager.myAnimeList.isLoggedIn) { - trackManager.myAnimeList.logout() + if (trackerManager.myAnimeList.isLoggedIn) { + trackerManager.myAnimeList.logout() context.toast(R.string.myanimelist_relogin) } } @@ -470,7 +470,7 @@ object Migrations { "pref_filter_library_started", "pref_filter_library_bookmarked", "pref_filter_library_completed", - ) + trackManager.services.map { "pref_filter_library_tracked_${it.id}" } + ) + trackerManager.trackers.map { "pref_filter_library_tracked_${it.id}" } prefKeys.forEach { key -> val pref = preferenceStore.getInt(key, 0) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupFileValidator.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupFileValidator.kt index 76d373e55..f0da251ec 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupFileValidator.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupFileValidator.kt @@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.data.backup import android.content.Context import android.net.Uri import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.util.BackupUtil import tachiyomi.domain.source.anime.service.AnimeSourceManager import tachiyomi.domain.source.manga.service.MangaSourceManager @@ -13,7 +13,7 @@ import uy.kohesive.injekt.api.get class BackupFileValidator( private val mangaSourceManager: MangaSourceManager = Injekt.get(), private val animeSourceManager: AnimeSourceManager = Injekt.get(), - private val trackManager: TrackManager = Injekt.get(), + private val trackerManager: TrackerManager = Injekt.get(), ) { /** @@ -70,7 +70,7 @@ class BackupFileValidator( .map { it.syncId } .distinct() val missingTrackers = trackers - .mapNotNull { trackManager.getService(it.toLong()) } + .mapNotNull { trackerManager.get(it.toLong()) } .filter { !it.isLoggedIn } .map { it.name } .sorted() diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/AnimeTrackService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/AnimeTracker.kt similarity index 97% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/AnimeTrackService.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/AnimeTracker.kt index 3abce61b8..a2c5d7159 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/AnimeTrackService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/AnimeTracker.kt @@ -1,7 +1,7 @@ package eu.kanade.tachiyomi.data.track import android.app.Application -import eu.kanade.domain.items.episode.interactor.SyncEpisodeProgressWithTrack +import eu.kanade.domain.track.anime.interactor.SyncEpisodeProgressWithTrack import eu.kanade.domain.track.anime.model.toDbTrack import eu.kanade.domain.track.anime.model.toDomainTrack import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack @@ -24,7 +24,7 @@ import tachiyomi.domain.track.anime.model.AnimeTrack as DomainAnimeTrack private val insertTrack: InsertAnimeTrack by injectLazy() private val syncEpisodeProgressWithTrack: SyncEpisodeProgressWithTrack by injectLazy() -interface AnimeTrackService { +interface AnimeTracker { // Common functions fun getCompletionStatus(): Int @@ -108,7 +108,7 @@ interface AnimeTrackService { } } - syncEpisodeProgressWithTrack.await(animeId, track, this@AnimeTrackService) + syncEpisodeProgressWithTrack.await(animeId, track, this@AnimeTracker) } } catch (e: Throwable) { withUIContext { Injekt.get().toast(e.message) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableAnimeTrackService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableAnimeTracker.kt similarity index 58% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableAnimeTrackService.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableAnimeTracker.kt index 3ea9c00c1..0d42df486 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableAnimeTrackService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableAnimeTracker.kt @@ -3,9 +3,9 @@ package eu.kanade.tachiyomi.data.track import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack /** - * For track services api that support deleting a manga entry for a user's list + *Tracker that support deleting am entry from a user's list */ -interface DeletableAnimeTrackService { +interface DeletableAnimeTracker { suspend fun delete(track: AnimeTrack): AnimeTrack } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableMangaTrackService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableMangaTracker.kt similarity index 58% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableMangaTrackService.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableMangaTracker.kt index 4a68ce4d2..552d8eeef 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableMangaTrackService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/DeletableMangaTracker.kt @@ -3,9 +3,9 @@ package eu.kanade.tachiyomi.data.track import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack /** - * For track services api that support deleting a manga entry for a user's list + * Tracker that support deleting am entry from a user's list */ -interface DeletableMangaTrackService { +interface DeletableMangaTracker { suspend fun delete(track: MangaTrack): MangaTrack } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/EnhancedAnimeTrackService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/EnhancedAnimeTracker.kt similarity index 82% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/EnhancedAnimeTrackService.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/EnhancedAnimeTracker.kt index 9fe34f667..cfd462f2d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/EnhancedAnimeTrackService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/EnhancedAnimeTracker.kt @@ -9,9 +9,9 @@ import tachiyomi.domain.track.anime.model.AnimeTrack * An Enhanced Track Service will never prompt the user to match a manga with the remote. * It is expected that such Track Service can only work with specific sources and unique IDs. */ -interface EnhancedAnimeTrackService { +interface EnhancedAnimeTracker { /** - * This TrackService will only work with the sources that are accepted by this filter function. + * This Tracker will only work with the sources that are accepted by this filter function. */ fun accept(source: AnimeSource): Boolean { return source::class.qualifiedName in getAcceptedSources() @@ -25,12 +25,12 @@ interface EnhancedAnimeTrackService { fun loginNoop() /** - * match is similar to TrackService.search, but only return zero or one match. + * match is similar to Tracker.search, but only return zero or one match. */ suspend fun match(anime: Anime): AnimeTrackSearch? /** - * Checks whether the provided source/track/anime triplet is from this AnimeTrackService + * Checks whether the provided source/track/anime triplet is from this AnimeTracker */ fun isTrackFrom(track: AnimeTrack, anime: Anime, source: AnimeSource?): Boolean diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/EnhancedMangaTrackService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/EnhancedMangaTracker.kt similarity index 69% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/EnhancedMangaTrackService.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/EnhancedMangaTracker.kt index 8b9acf394..80cc422e2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/EnhancedMangaTrackService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/EnhancedMangaTracker.kt @@ -6,12 +6,12 @@ import tachiyomi.domain.entries.manga.model.Manga import tachiyomi.domain.track.manga.model.MangaTrack /** - * An Enhanced Track Service will never prompt the user to match a manga with the remote. - * It is expected that such Track Service can only work with specific sources and unique IDs. + * A tracker that will never prompt the user to manually bind an entry. + * It is expected that such tracker can only work with specific sources and unique IDs. */ -interface EnhancedMangaTrackService { +interface EnhancedMangaTracker { /** - * This TrackService will only work with the sources that are accepted by this filter function. + * This Tracker will only work with the sources that are accepted by this filter function. */ fun accept(source: MangaSource): Boolean { return source::class.qualifiedName in getAcceptedSources() @@ -25,12 +25,12 @@ interface EnhancedMangaTrackService { fun loginNoop() /** - * match is similar to TrackService.search, but only return zero or one match. + * match is similar to Tracker.search, but only return zero or one match. */ suspend fun match(manga: Manga): MangaTrackSearch? /** - * Checks whether the provided source/track/manga triplet is from this TrackService + * Checks whether the provided source/track/manga triplet is from this [MangaTrack] */ fun isTrackFrom(track: MangaTrack, manga: Manga, source: MangaSource?): Boolean diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/MangaTrackService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/MangaTracker.kt similarity index 97% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/MangaTrackService.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/MangaTracker.kt index 1f1a219fc..077ce37c6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/MangaTrackService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/MangaTracker.kt @@ -1,7 +1,7 @@ package eu.kanade.tachiyomi.data.track import android.app.Application -import eu.kanade.domain.items.chapter.interactor.SyncChapterProgressWithTrack +import eu.kanade.domain.track.manga.interactor.SyncChapterProgressWithTrack import eu.kanade.domain.track.manga.model.toDbTrack import eu.kanade.domain.track.manga.model.toDomainTrack import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack @@ -24,7 +24,7 @@ import tachiyomi.domain.track.manga.model.MangaTrack as DomainTrack private val insertTrack: InsertMangaTrack by injectLazy() private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack by injectLazy() -interface MangaTrackService { +interface MangaTracker { // Common functions fun getCompletionStatus(): Int @@ -108,7 +108,7 @@ interface MangaTrackService { } } - syncChapterProgressWithTrack.await(mangaId, track, this@MangaTrackService) + syncChapterProgressWithTrack.await(mangaId, track, this@MangaTracker) } } catch (e: Throwable) { withUIContext { Injekt.get().toast(e.message) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/Tracker.kt similarity index 77% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/TrackService.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/Tracker.kt index fa60a220e..4a480a051 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/Tracker.kt @@ -9,7 +9,7 @@ import eu.kanade.tachiyomi.network.NetworkHelper import okhttp3.OkHttpClient import uy.kohesive.injekt.injectLazy -abstract class TrackService(val id: Long, val name: String) { +abstract class Tracker(val id: Long, val name: String) { val trackPreferences: TrackPreferences by injectLazy() val networkService: NetworkHelper by injectLazy() @@ -33,7 +33,7 @@ abstract class TrackService(val id: Long, val name: String) { @CallSuper open fun logout() { - trackPreferences.setTrackCredentials(this, "", "") + trackPreferences.setCredentials(this, "", "") } open val isLoggedIn: Boolean @@ -45,12 +45,12 @@ abstract class TrackService(val id: Long, val name: String) { fun getPassword() = trackPreferences.trackPassword(this).get() fun saveCredentials(username: String, password: String) { - trackPreferences.setTrackCredentials(this, username, password) + trackPreferences.setCredentials(this, username, password) } - open val animeService: AnimeTrackService - get() = this as AnimeTrackService + open val animeService: AnimeTracker + get() = this as AnimeTracker - open val mangaService: MangaTrackService - get() = this as MangaTrackService + open val mangaService: MangaTracker + get() = this as MangaTracker } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackerManager.kt similarity index 59% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/TrackManager.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/TrackerManager.kt index 482f00274..e68d6b780 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackerManager.kt @@ -12,35 +12,29 @@ import eu.kanade.tachiyomi.data.track.shikimori.Shikimori import eu.kanade.tachiyomi.data.track.simkl.Simkl import eu.kanade.tachiyomi.data.track.suwayomi.Suwayomi -class TrackManager(context: Context) { +class TrackerManager(context: Context) { companion object { - const val MYANIMELIST = 1L const val ANILIST = 2L const val KITSU = 3L - const val SHIKIMORI = 4L - const val BANGUMI = 5L - const val KOMGA = 6L - const val MANGA_UPDATES = 7L const val KAVITA = 8L - const val SUWAYOMI = 9L const val SIMKL = 101L } - val myAnimeList = MyAnimeList(MYANIMELIST) + val myAnimeList = MyAnimeList(1L) val aniList = Anilist(ANILIST) val kitsu = Kitsu(KITSU) - val shikimori = Shikimori(SHIKIMORI) - val bangumi = Bangumi(BANGUMI) - val komga = Komga(KOMGA) - val mangaUpdates = MangaUpdates(MANGA_UPDATES) + val shikimori = Shikimori(4L) + val bangumi = Bangumi(5L) + val komga = Komga(6L) + val mangaUpdates = MangaUpdates(7L) val kavita = Kavita(context, KAVITA) - val suwayomi = Suwayomi(SUWAYOMI) + val suwayomi = Suwayomi(9L) val simkl = Simkl(SIMKL) - val services = listOf(myAnimeList, aniList, kitsu, shikimori, bangumi, komga, mangaUpdates, kavita, suwayomi, simkl) + val trackers = listOf(myAnimeList, aniList, kitsu, shikimori, bangumi, komga, mangaUpdates, kavita, suwayomi, simkl) - fun getService(id: Long) = services.find { it.id == id } + fun get(id: Long) = trackers.find { it.id == id } - fun hasLoggedServices() = services.any { it.isLoggedIn } + fun hasLoggedIn() = trackers.any { it.isLoggedIn } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt index 4e6543d2e..7cde41d1a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt @@ -5,11 +5,11 @@ import androidx.annotation.StringRes import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.AnimeTrackService -import eu.kanade.tachiyomi.data.track.DeletableAnimeTrackService -import eu.kanade.tachiyomi.data.track.DeletableMangaTrackService -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.AnimeTracker +import eu.kanade.tachiyomi.data.track.DeletableAnimeTracker +import eu.kanade.tachiyomi.data.track.DeletableMangaTracker +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import kotlinx.serialization.decodeFromString @@ -19,7 +19,7 @@ import uy.kohesive.injekt.injectLazy import tachiyomi.domain.track.anime.model.AnimeTrack as DomainAnimeTrack import tachiyomi.domain.track.manga.model.MangaTrack as DomainTrack -class Anilist(id: Long) : TrackService(id, "AniList"), MangaTrackService, AnimeTrackService, DeletableMangaTrackService, DeletableAnimeTrackService { +class Anilist(id: Long) : Tracker(id, "AniList"), MangaTracker, AnimeTracker, DeletableMangaTracker, DeletableAnimeTracker { companion object { const val READING = 1 diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistModels.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistModels.kt index d1a1d7ae6..b5c76e434 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistModels.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistModels.kt @@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.data.track.anilist import eu.kanade.domain.track.service.TrackPreferences import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import kotlinx.serialization.Serializable @@ -22,7 +22,7 @@ data class ALManga( val total_chapters: Int, ) { - fun toTrack() = MangaTrackSearch.create(TrackManager.ANILIST).apply { + fun toTrack() = MangaTrackSearch.create(TrackerManager.ANILIST).apply { media_id = this@ALManga.media_id title = title_user_pref total_chapters = this@ALManga.total_chapters @@ -53,7 +53,7 @@ data class ALAnime( val total_episodes: Int, ) { - fun toTrack() = AnimeTrackSearch.create(TrackManager.ANILIST).apply { + fun toTrack() = AnimeTrackSearch.create(TrackerManager.ANILIST).apply { media_id = this@ALAnime.media_id title = title_user_pref total_episodes = this@ALAnime.total_episodes @@ -83,7 +83,7 @@ data class ALUserManga( val manga: ALManga, ) { - fun toTrack() = MangaTrack.create(TrackManager.ANILIST).apply { + fun toTrack() = MangaTrack.create(TrackerManager.ANILIST).apply { media_id = manga.media_id title = manga.title_user_pref status = toTrackStatus() @@ -95,7 +95,7 @@ data class ALUserManga( total_chapters = manga.total_chapters } - fun toTrackStatus() = when (list_status) { + private fun toTrackStatus() = when (list_status) { "CURRENT" -> Anilist.READING "COMPLETED" -> Anilist.COMPLETED "PAUSED" -> Anilist.PAUSED @@ -116,7 +116,7 @@ data class ALUserAnime( val anime: ALAnime, ) { - fun toTrack() = AnimeTrack.create(TrackManager.ANILIST).apply { + fun toTrack() = AnimeTrack.create(TrackerManager.ANILIST).apply { media_id = anime.media_id title = anime.title_user_pref status = toTrackStatus() @@ -128,7 +128,7 @@ data class ALUserAnime( total_episodes = anime.total_episodes } - fun toTrackStatus() = when (list_status) { + private fun toTrackStatus() = when (list_status) { "CURRENT" -> Anilist.WATCHING "COMPLETED" -> Anilist.COMPLETED "PAUSED" -> Anilist.PAUSED diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt index 4dc81ac4c..9786d0b18 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt @@ -5,9 +5,9 @@ import androidx.annotation.StringRes import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.AnimeTrackService -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.AnimeTracker +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import kotlinx.serialization.decodeFromString @@ -15,13 +15,13 @@ import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import uy.kohesive.injekt.injectLazy -class Bangumi(id: Long) : TrackService(id, "Bangumi"), MangaTrackService, AnimeTrackService { +class Bangumi(id: Long) : Tracker(id, "Bangumi"), MangaTracker, AnimeTracker { private val json: Json by injectLazy() private val interceptor by lazy { BangumiInterceptor(this) } - private val api by lazy { BangumiApi(client, interceptor) } + private val api by lazy { BangumiApi(id, client, interceptor) } override fun getScoreList(): List { return IntRange(0, 10).map(Int::toString) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt index 3d2b094ee..8749370cc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt @@ -4,7 +4,6 @@ import android.net.Uri import androidx.core.net.toUri import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import eu.kanade.tachiyomi.network.GET @@ -29,7 +28,11 @@ import uy.kohesive.injekt.injectLazy import java.net.URLEncoder import java.nio.charset.StandardCharsets -class BangumiApi(private val client: OkHttpClient, interceptor: BangumiInterceptor) { +class BangumiApi( + private val trackId: Long, + private val client: OkHttpClient, + interceptor: BangumiInterceptor, +) { private val json: Json by injectLazy() @@ -175,7 +178,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept } else { 0 } - return MangaTrackSearch.create(TrackManager.BANGUMI).apply { + return MangaTrackSearch.create(trackId).apply { media_id = obj["id"]!!.jsonPrimitive.long title = obj["name_cn"]!!.jsonPrimitive.content cover_url = coverUrl @@ -197,7 +200,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept } else { 0 } - return AnimeTrackSearch.create(TrackManager.BANGUMI).apply { + return AnimeTrackSearch.create(trackId).apply { media_id = obj["id"]!!.jsonPrimitive.long title = obj["name_cn"]!!.jsonPrimitive.content cover_url = coverUrl diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/kavita/Kavita.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/kavita/Kavita.kt index 15d221c2d..bb2407d87 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/kavita/Kavita.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/kavita/Kavita.kt @@ -1,21 +1,25 @@ package eu.kanade.tachiyomi.data.track.kavita import android.content.Context -import android.content.SharedPreferences import android.graphics.Color import androidx.annotation.StringRes +import com.google.common.base.Strings.isNullOrEmpty import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.EnhancedMangaTrackService -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.EnhancedMangaTracker +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch +import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.MangaSource +import eu.kanade.tachiyomi.source.sourcePreferences import tachiyomi.domain.entries.manga.model.Manga +import tachiyomi.domain.source.manga.service.MangaSourceManager +import uy.kohesive.injekt.injectLazy import java.security.MessageDigest import tachiyomi.domain.track.manga.model.MangaTrack as DomainTrack -class Kavita(private val context: Context, id: Long) : TrackService(id, "Kavita"), EnhancedMangaTrackService, MangaTrackService { +class Kavita(private val context: Context, id: Long) : Tracker(id, "Kavita"), EnhancedMangaTracker, MangaTracker { companion object { const val UNREAD = 1 @@ -28,6 +32,8 @@ class Kavita(private val context: Context, id: Long) : TrackService(id, "Kavita" private val interceptor by lazy { KavitaInterceptor(this) } val api by lazy { KavitaApi(client, interceptor) } + private val sourceManager: MangaSourceManager by injectLazy() + override fun getLogo(): Int = R.drawable.ic_tracker_kavita override fun getLogoColor() = Color.rgb(74, 198, 148) @@ -84,7 +90,7 @@ class Kavita(private val context: Context, id: Long) : TrackService(id, "Kavita" saveCredentials("user", "pass") } - // TrackService.isLogged works by checking that credentials are saved. + // [Tracker].isLogged works by checking that credentials are saved. // By saving dummy, unused credentials, we can activate the tracker simply by login/logout override fun loginNoop() { saveCredentials("user", "pass") @@ -111,28 +117,29 @@ class Kavita(private val context: Context, id: Long) : TrackService(id, "Kavita" fun loadOAuth() { val oauth = OAuth() - for (sourceId in 1..3) { - val authentication = oauth.authentications[sourceId - 1] - val sourceSuffixID by lazy { - val key = "kavita_$sourceId/all/1" // Hardcoded versionID to 1 + for (id in 1..3) { + val authentication = oauth.authentications[id - 1] + val sourceId by lazy { + val key = "kavita_$id/all/1" // Hardcoded versionID to 1 val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray()) (0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) } .reduce(Long::or) and Long.MAX_VALUE } - val preferences: SharedPreferences by lazy { - context.getSharedPreferences("source_$sourceSuffixID", 0x0000) - } - val prefApiUrl = preferences.getString("APIURL", "")!! - if (prefApiUrl.isEmpty()) { + val preferences = (sourceManager.get(sourceId) as ConfigurableSource).sourcePreferences() + + val prefApiUrl = preferences.getString("APIURL", "") + val prefApiKey = preferences.getString("APIKEY", "") + if (prefApiUrl.isNullOrEmpty() || prefApiKey.isNullOrEmpty()) { // Source not configured. Skip continue } - val prefApiKey = preferences.getString("APIKEY", "")!! + val token = api.getNewToken(apiUrl = prefApiUrl, apiKey = prefApiKey) if (token.isNullOrEmpty()) { // Source is not accessible. Skip continue } + authentication.apiUrl = prefApiUrl authentication.jwtToken = token.toString() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/kavita/KavitaModels.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/kavita/KavitaModels.kt index 0e308b987..fe40cfabb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/kavita/KavitaModels.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/kavita/KavitaModels.kt @@ -1,6 +1,6 @@ package eu.kanade.tachiyomi.data.track.kavita -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import kotlinx.serialization.Serializable @@ -22,7 +22,7 @@ data class SeriesDto( val libraryId: Int, val libraryName: String? = "", ) { - fun toTrack(): MangaTrackSearch = MangaTrackSearch.create(TrackManager.KAVITA).also { + fun toTrack(): MangaTrackSearch = MangaTrackSearch.create(TrackerManager.KAVITA).also { it.title = name it.summary = "" } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt index ddc2bf7aa..f455f7c7e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt @@ -5,11 +5,11 @@ import androidx.annotation.StringRes import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.AnimeTrackService -import eu.kanade.tachiyomi.data.track.DeletableAnimeTrackService -import eu.kanade.tachiyomi.data.track.DeletableMangaTrackService -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.AnimeTracker +import eu.kanade.tachiyomi.data.track.DeletableAnimeTracker +import eu.kanade.tachiyomi.data.track.DeletableMangaTracker +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import kotlinx.serialization.decodeFromString @@ -18,7 +18,7 @@ import kotlinx.serialization.json.Json import uy.kohesive.injekt.injectLazy import java.text.DecimalFormat -class Kitsu(id: Long) : TrackService(id, "Kitsu"), AnimeTrackService, MangaTrackService, DeletableMangaTrackService, DeletableAnimeTrackService { +class Kitsu(id: Long) : Tracker(id, "Kitsu"), AnimeTracker, MangaTracker, DeletableMangaTracker, DeletableAnimeTracker { companion object { const val READING = 1 diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuModels.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuModels.kt index 9f4e29d67..95e83a2d8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuModels.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuModels.kt @@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.data.track.kitsu import androidx.annotation.CallSuper import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import kotlinx.serialization.Serializable @@ -37,7 +37,7 @@ class KitsuSearchManga(obj: JsonObject) { private val endDate = obj["endDate"]?.jsonPrimitive?.contentOrNull @CallSuper - fun toTrack() = MangaTrackSearch.create(TrackManager.KITSU).apply { + fun toTrack() = MangaTrackSearch.create(TrackerManager.KITSU).apply { media_id = this@KitsuSearchManga.id title = canonicalTitle total_chapters = chapterCount ?: 0 @@ -73,7 +73,7 @@ class KitsuSearchAnime(obj: JsonObject) { private val endDate = obj["endDate"]?.jsonPrimitive?.contentOrNull @CallSuper - fun toTrack() = AnimeTrackSearch.create(TrackManager.KITSU).apply { + fun toTrack() = AnimeTrackSearch.create(TrackerManager.KITSU).apply { media_id = this@KitsuSearchAnime.id title = canonicalTitle total_episodes = episodeCount ?: 0 @@ -105,7 +105,7 @@ class KitsuLibManga(obj: JsonObject, manga: JsonObject) { private val ratingTwenty = obj["attributes"]!!.jsonObject["ratingTwenty"]?.jsonPrimitive?.contentOrNull val progress = obj["attributes"]!!.jsonObject["progress"]!!.jsonPrimitive.int - fun toTrack() = MangaTrackSearch.create(TrackManager.KITSU).apply { + fun toTrack() = MangaTrackSearch.create(TrackerManager.KITSU).apply { media_id = libraryId title = canonicalTitle total_chapters = chapterCount ?: 0 @@ -147,7 +147,7 @@ class KitsuLibAnime(obj: JsonObject, anime: JsonObject) { private val ratingTwenty = obj["attributes"]!!.jsonObject["ratingTwenty"]?.jsonPrimitive?.contentOrNull val progress = obj["attributes"]!!.jsonObject["progress"]!!.jsonPrimitive.int - fun toTrack() = AnimeTrackSearch.create(TrackManager.KITSU).apply { + fun toTrack() = AnimeTrackSearch.create(TrackerManager.KITSU).apply { media_id = libraryId title = canonicalTitle total_episodes = episodeCount ?: 0 diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/komga/Komga.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/komga/Komga.kt index 8cdc3b268..c394d04a3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/komga/Komga.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/komga/Komga.kt @@ -4,9 +4,9 @@ import android.graphics.Color import androidx.annotation.StringRes import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.EnhancedMangaTrackService -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.EnhancedMangaTracker +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import eu.kanade.tachiyomi.source.MangaSource import okhttp3.Dns @@ -14,7 +14,7 @@ import okhttp3.OkHttpClient import tachiyomi.domain.entries.manga.model.Manga import tachiyomi.domain.track.manga.model.MangaTrack as DomainTrack -class Komga(id: Long) : TrackService(id, "Komga"), EnhancedMangaTrackService, MangaTrackService { +class Komga(id: Long) : Tracker(id, "Komga"), EnhancedMangaTracker, MangaTracker { companion object { const val UNREAD = 1 @@ -27,7 +27,7 @@ class Komga(id: Long) : TrackService(id, "Komga"), EnhancedMangaTrackService, Ma .dns(Dns.SYSTEM) // don't use DNS over HTTPS as it breaks IP addressing .build() - val api by lazy { KomgaApi(client) } + val api by lazy { KomgaApi(id, client) } override fun getLogo() = R.drawable.ic_tracker_komga @@ -86,7 +86,7 @@ class Komga(id: Long) : TrackService(id, "Komga"), EnhancedMangaTrackService, Ma saveCredentials("user", "pass") } - // TrackService.isLogged works by checking that credentials are saved. + // [Tracker].isLogged works by checking that credentials are saved. // By saving dummy, unused credentials, we can activate the tracker simply by login/logout override fun loginNoop() { saveCredentials("user", "pass") diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/komga/KomgaApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/komga/KomgaApi.kt index 8e94d08f8..1c07df169 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/komga/KomgaApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/komga/KomgaApi.kt @@ -1,7 +1,6 @@ package eu.kanade.tachiyomi.data.track.komga import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.awaitSuccess @@ -19,7 +18,10 @@ import uy.kohesive.injekt.injectLazy private const val READLIST_API = "/api/v1/readlists" -class KomgaApi(private val client: OkHttpClient) { +class KomgaApi( + private val trackId: Long, + private val client: OkHttpClient, +) { private val json: Json by injectLazy() @@ -91,14 +93,14 @@ class KomgaApi(private val client: OkHttpClient) { return getTrackSearch(track.tracking_url) } - private fun SeriesDto.toTrack(): MangaTrackSearch = MangaTrackSearch.create(TrackManager.KOMGA).also { + private fun SeriesDto.toTrack(): MangaTrackSearch = MangaTrackSearch.create(trackId).also { it.title = metadata.title it.summary = metadata.summary it.publishing_status = metadata.status } private fun ReadListDto.toTrack(): MangaTrackSearch = MangaTrackSearch.create( - TrackManager.KOMGA, + trackId, ).also { it.title = name } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/mangaupdates/MangaUpdates.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/mangaupdates/MangaUpdates.kt index 3d100dc26..f15189368 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/mangaupdates/MangaUpdates.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/mangaupdates/MangaUpdates.kt @@ -4,14 +4,14 @@ import android.graphics.Color import androidx.annotation.StringRes import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.DeletableMangaTrackService -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.DeletableMangaTracker +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.mangaupdates.dto.copyTo import eu.kanade.tachiyomi.data.track.mangaupdates.dto.toTrackSearch import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch -class MangaUpdates(id: Long) : TrackService(id, "MangaUpdates"), MangaTrackService, DeletableMangaTrackService { +class MangaUpdates(id: Long) : Tracker(id, "MangaUpdates"), MangaTracker, DeletableMangaTracker { companion object { const val READING_LIST = 0 diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt index 23b0278fa..a83d8b3f4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt @@ -5,11 +5,11 @@ import androidx.annotation.StringRes import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.AnimeTrackService -import eu.kanade.tachiyomi.data.track.DeletableAnimeTrackService -import eu.kanade.tachiyomi.data.track.DeletableMangaTrackService -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.AnimeTracker +import eu.kanade.tachiyomi.data.track.DeletableAnimeTracker +import eu.kanade.tachiyomi.data.track.DeletableMangaTracker +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import kotlinx.serialization.decodeFromString @@ -17,7 +17,7 @@ import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import uy.kohesive.injekt.injectLazy -class MyAnimeList(id: Long) : TrackService(id, "MyAnimeList"), MangaTrackService, AnimeTrackService, DeletableMangaTrackService, DeletableAnimeTrackService { +class MyAnimeList(id: Long) : Tracker(id, "MyAnimeList"), MangaTracker, AnimeTracker, DeletableMangaTracker, DeletableAnimeTracker { companion object { const val READING = 1 @@ -37,7 +37,7 @@ class MyAnimeList(id: Long) : TrackService(id, "MyAnimeList"), MangaTrackService private val json: Json by injectLazy() private val interceptor by lazy { MyAnimeListInterceptor(this, getPassword()) } - private val api by lazy { MyAnimeListApi(client, interceptor) } + private val api by lazy { MyAnimeListApi(id, client, interceptor) } override val supportsReadingDates: Boolean = true diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt index b11369d5f..dfa0bc4f8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt @@ -4,7 +4,6 @@ import android.net.Uri import androidx.core.net.toUri import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import eu.kanade.tachiyomi.network.GET @@ -34,7 +33,11 @@ import uy.kohesive.injekt.injectLazy import java.text.SimpleDateFormat import java.util.Locale -class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListInterceptor) { +class MyAnimeListApi( + private val trackId: Long, + private val client: OkHttpClient, + interceptor: MyAnimeListInterceptor, +) { private val json: Json by injectLazy() @@ -136,7 +139,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI .parseAs() .let { val obj = it.jsonObject - MangaTrackSearch.create(TrackManager.MYANIMELIST).apply { + MangaTrackSearch.create(trackId).apply { media_id = obj["id"]!!.jsonPrimitive.long title = obj["title"]!!.jsonPrimitive.content summary = obj["synopsis"]?.jsonPrimitive?.content ?: "" @@ -176,7 +179,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI .parseAs() .let { val obj = it.jsonObject - AnimeTrackSearch.create(TrackManager.MYANIMELIST).apply { + AnimeTrackSearch.create(trackId).apply { media_id = obj["id"]!!.jsonPrimitive.long title = obj["title"]!!.jsonPrimitive.content summary = obj["synopsis"]?.jsonPrimitive?.content ?: "" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt index e953e7f0e..af8f66021 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt @@ -5,11 +5,11 @@ import androidx.annotation.StringRes import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.AnimeTrackService -import eu.kanade.tachiyomi.data.track.DeletableAnimeTrackService -import eu.kanade.tachiyomi.data.track.DeletableMangaTrackService -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.AnimeTracker +import eu.kanade.tachiyomi.data.track.DeletableAnimeTracker +import eu.kanade.tachiyomi.data.track.DeletableMangaTracker +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import kotlinx.serialization.decodeFromString @@ -17,7 +17,7 @@ import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import uy.kohesive.injekt.injectLazy -class Shikimori(id: Long) : TrackService(id, "Shikimori"), MangaTrackService, AnimeTrackService, DeletableMangaTrackService, DeletableAnimeTrackService { +class Shikimori(id: Long) : Tracker(id, "Shikimori"), MangaTracker, AnimeTracker, DeletableMangaTracker, DeletableAnimeTracker { companion object { const val READING = 1 @@ -32,7 +32,7 @@ class Shikimori(id: Long) : TrackService(id, "Shikimori"), MangaTrackService, An private val interceptor by lazy { ShikimoriInterceptor(this) } - private val api by lazy { ShikimoriApi(client, interceptor) } + private val api by lazy { ShikimoriApi(id, client, interceptor) } override fun getScoreList(): List { return IntRange(0, 10).map(Int::toString) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt index f8e5639d2..7160e74a7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt @@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.track.shikimori import androidx.core.net.toUri import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import eu.kanade.tachiyomi.network.DELETE @@ -30,7 +29,11 @@ import okhttp3.RequestBody.Companion.toRequestBody import tachiyomi.core.util.lang.withIOContext import uy.kohesive.injekt.injectLazy -class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInterceptor) { +class ShikimoriApi( + private val trackId: Long, + private val client: OkHttpClient, + interceptor: ShikimoriInterceptor, +) { private val json: Json by injectLazy() @@ -165,7 +168,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter } private fun jsonToSearch(obj: JsonObject): MangaTrackSearch { - return MangaTrackSearch.create(TrackManager.SHIKIMORI).apply { + return MangaTrackSearch.create(trackId).apply { media_id = obj["id"]!!.jsonPrimitive.long title = obj["name"]!!.jsonPrimitive.content total_chapters = obj["chapters"]!!.jsonPrimitive.int @@ -179,7 +182,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter } private fun jsonToAnimeSearch(obj: JsonObject): AnimeTrackSearch { - return AnimeTrackSearch.create(TrackManager.SHIKIMORI).apply { + return AnimeTrackSearch.create(trackId).apply { media_id = obj["id"]!!.jsonPrimitive.long title = obj["name"]!!.jsonPrimitive.content total_episodes = obj["episodes"]!!.jsonPrimitive.int @@ -193,7 +196,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter } private fun jsonToTrack(obj: JsonObject, mangas: JsonObject): MangaTrack { - return MangaTrack.create(TrackManager.SHIKIMORI).apply { + return MangaTrack.create(trackId).apply { title = mangas["name"]!!.jsonPrimitive.content media_id = obj["id"]!!.jsonPrimitive.long total_chapters = mangas["chapters"]!!.jsonPrimitive.int @@ -206,7 +209,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter } private fun jsonToAnimeTrack(obj: JsonObject, animes: JsonObject): AnimeTrack { - return AnimeTrack.create(TrackManager.SHIKIMORI).apply { + return AnimeTrack.create(trackId).apply { title = animes["name"]!!.jsonPrimitive.content media_id = obj["id"]!!.jsonPrimitive.long total_episodes = animes["episodes"]!!.jsonPrimitive.int diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/simkl/Simkl.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/simkl/Simkl.kt index 8bd847090..b7e491b45 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/simkl/Simkl.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/simkl/Simkl.kt @@ -4,15 +4,15 @@ import android.graphics.Color import androidx.annotation.StringRes import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack -import eu.kanade.tachiyomi.data.track.AnimeTrackService -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.AnimeTracker +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import uy.kohesive.injekt.injectLazy -class Simkl(id: Long) : TrackService(id, "Simkl"), AnimeTrackService { +class Simkl(id: Long) : Tracker(id, "Simkl"), AnimeTracker { companion object { const val WATCHING = 1 diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/simkl/SimklApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/simkl/SimklApi.kt index 519da7060..2ec9e22c2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/simkl/SimklApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/simkl/SimklApi.kt @@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.data.track.simkl import android.net.Uri import androidx.core.net.toUri import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.POST @@ -167,7 +167,7 @@ class SimklApi(private val client: OkHttpClient, interceptor: SimklInterceptor) } private fun jsonToAnimeSearch(obj: JsonObject, type: String): AnimeTrackSearch { - return AnimeTrackSearch.create(TrackManager.SIMKL).apply { + return AnimeTrackSearch.create(TrackerManager.SIMKL).apply { media_id = obj["ids"]!!.jsonObject["simkl_id"]!!.jsonPrimitive.long title = obj["title_romaji"]?.jsonPrimitive?.content ?: obj["title"]!!.jsonPrimitive.content total_episodes = obj["ep_count"]?.jsonPrimitive?.intOrNull ?: 1 @@ -186,7 +186,7 @@ class SimklApi(private val client: OkHttpClient, interceptor: SimklInterceptor) type: String, statusString: String, ): AnimeTrack { - return AnimeTrack.create(TrackManager.SIMKL).apply { + return AnimeTrack.create(TrackerManager.SIMKL).apply { title = obj[typeName]!!.jsonObject["title"]!!.jsonPrimitive.content val id = obj[typeName]!!.jsonObject["ids"]!!.jsonObject["simkl"]!!.jsonPrimitive.long media_id = id diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/Suwayomi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/Suwayomi.kt index cecb41020..f5f5e6843 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/Suwayomi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/Suwayomi.kt @@ -4,16 +4,17 @@ import android.graphics.Color import androidx.annotation.StringRes import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.EnhancedMangaTrackService -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.EnhancedMangaTracker +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import eu.kanade.tachiyomi.source.MangaSource import tachiyomi.domain.entries.manga.model.Manga as DomainManga import tachiyomi.domain.track.manga.model.MangaTrack as DomainTrack -class Suwayomi(id: Long) : TrackService(id, "Suwayomi"), EnhancedMangaTrackService, MangaTrackService { - val api by lazy { TachideskApi() } +class Suwayomi(id: Long) : Tracker(id, "Suwayomi"), EnhancedMangaTracker, MangaTracker { + + val api by lazy { SuwayomiApi(id) } override fun getLogo() = R.drawable.ic_tracker_suwayomi diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/TachideskApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/SuwayomiApi.kt similarity index 88% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/TachideskApi.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/SuwayomiApi.kt index 77f60b4f1..070c470bb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/TachideskApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/SuwayomiApi.kt @@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.track.suwayomi import android.app.Application import android.content.SharedPreferences import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack -import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.NetworkHelper @@ -23,7 +22,7 @@ import uy.kohesive.injekt.injectLazy import java.nio.charset.Charset import java.security.MessageDigest -class TachideskApi { +class SuwayomiApi(private val trackId: Long) { private val network by injectLazy() private val json: Json by injectLazy() @@ -62,7 +61,7 @@ class TachideskApi { .parseAs() } - MangaTrackSearch.create(TrackManager.SUWAYOMI).apply { + MangaTrackSearch.create(trackId).apply { title = manga.title cover_url = "$url/thumbnail" summary = manga.description.orEmpty() @@ -101,14 +100,14 @@ class TachideskApi { return getTrackSearch(track.tracking_url) } - private val tachideskExtensionId by lazy { + private val sourceId by lazy { val key = "tachidesk/en/1" val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray()) (0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }.reduce(Long::or) and Long.MAX_VALUE } private val preferences: SharedPreferences by lazy { - Injekt.get().getSharedPreferences("source_$tachideskExtensionId", 0x0000) + Injekt.get().getSharedPreferences("source_$sourceId", 0x0000) } private fun getPrefBaseUrl(): String = preferences.getString(ADDRESS_TITLE, ADDRESS_DEFAULT)!! @@ -117,13 +116,11 @@ class TachideskApi { PASSWORD_TITLE, PASSWORD_DEFAULT, )!! - - companion object { - private const val ADDRESS_TITLE = "Server URL Address" - private const val ADDRESS_DEFAULT = "" - private const val LOGIN_TITLE = "Login (Basic Auth)" - private const val LOGIN_DEFAULT = "" - private const val PASSWORD_TITLE = "Password (Basic Auth)" - private const val PASSWORD_DEFAULT = "" - } } + +private const val ADDRESS_TITLE = "Server URL Address" +private const val ADDRESS_DEFAULT = "" +private const val LOGIN_TITLE = "Login (Basic Auth)" +private const val LOGIN_DEFAULT = "" +private const val PASSWORD_TITLE = "Password (Basic Auth)" +private const val PASSWORD_DEFAULT = "" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/TachideskDto.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/SuwayomiModels.kt similarity index 100% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/TachideskDto.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/suwayomi/SuwayomiModels.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/anime/AnimeSourceExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/source/anime/AnimeSourceExtensions.kt index 8d1b087c5..b69f29e65 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/anime/AnimeSourceExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/anime/AnimeSourceExtensions.kt @@ -11,8 +11,6 @@ import uy.kohesive.injekt.api.get fun AnimeSource.icon(): Drawable? = Injekt.get().getAppIconForSource(this.id) -fun AnimeSource.getPreferenceKey(): String = "source_$id" - fun AnimeSource.toStubSource(): StubAnimeSource = StubAnimeSource(id = id, lang = lang, name = name) fun AnimeSource.getNameForAnimeInfo(): String { diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/manga/MangaSourceExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/source/manga/MangaSourceExtensions.kt index 61f4cdba2..18c39eeeb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/manga/MangaSourceExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/manga/MangaSourceExtensions.kt @@ -11,8 +11,6 @@ import uy.kohesive.injekt.api.get fun MangaSource.icon(): Drawable? = Injekt.get().getAppIconForSource(this.id) -fun MangaSource.getPreferenceKey(): String = "source_$id" - fun MangaSource.toStubSource(): StubMangaSource = StubMangaSource(id = id, lang = lang, name = name) fun MangaSource.getNameForMangaInfo(): String { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/extension/details/SourcePreferencesScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/extension/details/SourcePreferencesScreen.kt index 276e58187..43537c1df 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/extension/details/SourcePreferencesScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/extension/details/SourcePreferencesScreen.kt @@ -38,8 +38,8 @@ import eu.kanade.presentation.components.UpIcon import eu.kanade.presentation.util.Screen import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource +import eu.kanade.tachiyomi.animesource.sourcePreferences import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore -import eu.kanade.tachiyomi.source.anime.getPreferenceKey import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito import tachiyomi.domain.source.anime.service.AnimeSourceManager import tachiyomi.presentation.core.components.material.Scaffold @@ -138,15 +138,9 @@ class SourcePreferencesFragment : PreferenceFragmentCompat() { private fun populateScreen(): PreferenceScreen { val sourceId = requireArguments().getLong(SOURCE_ID) - val source = Injekt.get().get(sourceId)!! + val source = Injekt.get().get(sourceId)!! as ConfigurableAnimeSource - check(source is ConfigurableAnimeSource) - - val sharedPreferences = requireContext().getSharedPreferences( - source.getPreferenceKey(), - Context.MODE_PRIVATE, - ) - val dataStore = SharedPreferencesDataStore(sharedPreferences) + val dataStore = SharedPreferencesDataStore(source.sourcePreferences()) preferenceManager.preferenceDataStore = dataStore val sourceScreen = preferenceManager.createPreferenceScreen(requireContext()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/migration/search/MigrateAnimeDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/migration/search/MigrateAnimeDialog.kt index b59202fce..9bac9ba8c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/migration/search/MigrateAnimeDialog.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/migration/search/MigrateAnimeDialog.kt @@ -37,8 +37,8 @@ import eu.kanade.tachiyomi.animesource.AnimeSource import eu.kanade.tachiyomi.animesource.model.SEpisode import eu.kanade.tachiyomi.data.cache.AnimeCoverCache import eu.kanade.tachiyomi.data.download.anime.AnimeDownloadManager -import eu.kanade.tachiyomi.data.track.EnhancedAnimeTrackService -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.EnhancedAnimeTracker +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.ui.browse.anime.migration.AnimeMigrationFlags import kotlinx.coroutines.flow.update import tachiyomi.core.preference.Preference @@ -180,7 +180,7 @@ internal class MigrateAnimeDialogScreenModel( } private val enhancedServices by lazy { - Injekt.get().services.filterIsInstance() + Injekt.get().trackers.filterIsInstance() } suspend fun migrateAnime( diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/source/browse/BrowseAnimeSourceScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/source/browse/BrowseAnimeSourceScreenModel.kt index 06a7967af..86d9c83f6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/source/browse/BrowseAnimeSourceScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/source/browse/BrowseAnimeSourceScreenModel.kt @@ -17,16 +17,12 @@ import eu.kanade.core.preference.asState import eu.kanade.domain.base.BasePreferences import eu.kanade.domain.entries.anime.interactor.UpdateAnime import eu.kanade.domain.entries.anime.model.toDomainAnime -import eu.kanade.domain.items.episode.interactor.SyncEpisodeProgressWithTrack import eu.kanade.domain.source.service.SourcePreferences -import eu.kanade.domain.track.anime.model.toDomainTrack +import eu.kanade.domain.track.anime.interactor.AddAnimeTracks import eu.kanade.presentation.util.ioCoroutineScope import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource import eu.kanade.tachiyomi.animesource.model.AnimeFilterList import eu.kanade.tachiyomi.data.cache.AnimeCoverCache -import eu.kanade.tachiyomi.data.track.EnhancedAnimeTrackService -import eu.kanade.tachiyomi.data.track.TrackManager -import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.util.removeCovers import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.distinctUntilChanged @@ -37,11 +33,9 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import logcat.LogPriority import tachiyomi.core.preference.CheckboxState import tachiyomi.core.preference.mapAsCheckboxState import tachiyomi.core.util.lang.launchIO -import tachiyomi.core.util.system.logcat import tachiyomi.domain.category.anime.interactor.GetAnimeCategories import tachiyomi.domain.category.anime.interactor.SetAnimeCategories import tachiyomi.domain.category.model.Category @@ -54,7 +48,6 @@ import tachiyomi.domain.items.episode.interactor.SetAnimeDefaultEpisodeFlags import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.source.anime.interactor.GetRemoteAnime import tachiyomi.domain.source.anime.service.AnimeSourceManager -import tachiyomi.domain.track.anime.interactor.InsertAnimeTrack import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import java.util.Date @@ -76,12 +69,9 @@ class BrowseAnimeSourceScreenModel( private val getAnime: GetAnime = Injekt.get(), private val networkToLocalAnime: NetworkToLocalAnime = Injekt.get(), private val updateAnime: UpdateAnime = Injekt.get(), - private val insertTrack: InsertAnimeTrack = Injekt.get(), - private val syncEpisodeProgressWithTrack: SyncEpisodeProgressWithTrack = Injekt.get(), + private val addTracks: AddAnimeTracks = Injekt.get(), ) : StateScreenModel(State(Listing.valueOf(listingQuery))) { - private val loggedServices by lazy { Injekt.get().services.filter { it.isLoggedIn } } - var displayMode by sourcePreferences.sourceDisplayMode().asState(coroutineScope) val source = sourceManager.getOrStub(sourceId) @@ -242,8 +232,7 @@ class BrowseAnimeSourceScreenModel( new = new.removeCovers(coverCache) } else { setAnimeDefaultEpisodeFlags.await(anime) - - autoAddTrack(anime) + addTracks.bindEnhancedTracks(anime, source) } updateAnime.await(new.toAnimeUpdate()) @@ -284,31 +273,6 @@ class BrowseAnimeSourceScreenModel( } } - private suspend fun autoAddTrack(anime: Anime) { - loggedServices - .filterIsInstance() - .filter { it.accept(source) } - .forEach { service -> - try { - service.match(anime)?.let { track -> - track.anime_id = anime.id - (service as TrackService).animeService.bind(track) - insertTrack.await(track.toDomainTrack()!!) - syncEpisodeProgressWithTrack.await( - anime.id, - track.toDomainTrack()!!, - service.animeService, - ) - } - } catch (e: Exception) { - logcat( - LogPriority.WARN, - e, - ) { "Could not match anime: ${anime.title} with service $service" } - } - } - } - /** * Get user categories. * diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/extension/details/MangaSourcePreferencesScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/extension/details/MangaSourcePreferencesScreen.kt index ca668f6bb..082623b41 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/extension/details/MangaSourcePreferencesScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/extension/details/MangaSourcePreferencesScreen.kt @@ -39,7 +39,7 @@ import eu.kanade.presentation.util.Screen import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore import eu.kanade.tachiyomi.source.ConfigurableSource -import eu.kanade.tachiyomi.source.manga.getPreferenceKey +import eu.kanade.tachiyomi.source.sourcePreferences import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito import tachiyomi.domain.source.manga.service.MangaSourceManager import tachiyomi.presentation.core.components.material.Scaffold @@ -138,15 +138,9 @@ class MangaSourcePreferencesFragment : PreferenceFragmentCompat() { private fun populateScreen(): PreferenceScreen { val sourceId = requireArguments().getLong(SOURCE_ID) - val source = Injekt.get().get(sourceId)!! + val source = Injekt.get().get(sourceId)!! as ConfigurableSource - check(source is ConfigurableSource) - - val sharedPreferences = requireContext().getSharedPreferences( - source.getPreferenceKey(), - Context.MODE_PRIVATE, - ) - val dataStore = SharedPreferencesDataStore(sharedPreferences) + val dataStore = SharedPreferencesDataStore(source.sourcePreferences()) preferenceManager.preferenceDataStore = dataStore val sourceScreen = preferenceManager.createPreferenceScreen(requireContext()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/migration/search/MigrateMangaDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/migration/search/MigrateMangaDialog.kt index 1514af78b..baf2b92ad 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/migration/search/MigrateMangaDialog.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/migration/search/MigrateMangaDialog.kt @@ -35,8 +35,8 @@ import eu.kanade.domain.items.chapter.interactor.SyncChaptersWithSource import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.cache.MangaCoverCache import eu.kanade.tachiyomi.data.download.manga.MangaDownloadManager -import eu.kanade.tachiyomi.data.track.EnhancedMangaTrackService -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.EnhancedMangaTracker +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.source.MangaSource import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.ui.browse.manga.migration.MangaMigrationFlags @@ -180,7 +180,7 @@ internal class MigrateMangaDialogScreenModel( } private val enhancedServices by lazy { - Injekt.get().services.filterIsInstance() + Injekt.get().trackers.filterIsInstance() } suspend fun migrateManga( diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/source/browse/BrowseMangaSourceScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/source/browse/BrowseMangaSourceScreenModel.kt index 8e00d2443..bdb635886 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/source/browse/BrowseMangaSourceScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/source/browse/BrowseMangaSourceScreenModel.kt @@ -17,14 +17,10 @@ import eu.kanade.core.preference.asState import eu.kanade.domain.base.BasePreferences import eu.kanade.domain.entries.manga.interactor.UpdateManga import eu.kanade.domain.entries.manga.model.toDomainManga -import eu.kanade.domain.items.chapter.interactor.SyncChapterProgressWithTrack import eu.kanade.domain.source.service.SourcePreferences -import eu.kanade.domain.track.manga.model.toDomainTrack +import eu.kanade.domain.track.manga.interactor.AddMangaTracks import eu.kanade.presentation.util.ioCoroutineScope import eu.kanade.tachiyomi.data.cache.MangaCoverCache -import eu.kanade.tachiyomi.data.track.EnhancedMangaTrackService -import eu.kanade.tachiyomi.data.track.TrackManager -import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.util.removeCovers @@ -37,11 +33,9 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import logcat.LogPriority import tachiyomi.core.preference.CheckboxState import tachiyomi.core.preference.mapAsCheckboxState import tachiyomi.core.util.lang.launchIO -import tachiyomi.core.util.system.logcat import tachiyomi.domain.category.manga.interactor.GetMangaCategories import tachiyomi.domain.category.manga.interactor.SetMangaCategories import tachiyomi.domain.category.model.Category @@ -54,7 +48,6 @@ import tachiyomi.domain.items.chapter.interactor.SetMangaDefaultChapterFlags import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.source.manga.interactor.GetRemoteManga import tachiyomi.domain.source.manga.service.MangaSourceManager -import tachiyomi.domain.track.manga.interactor.InsertMangaTrack import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import java.util.Date @@ -76,12 +69,9 @@ class BrowseMangaSourceScreenModel( private val getManga: GetManga = Injekt.get(), private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), private val updateManga: UpdateManga = Injekt.get(), - private val insertTrack: InsertMangaTrack = Injekt.get(), - private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack = Injekt.get(), + private val addTracks: AddMangaTracks = Injekt.get(), ) : StateScreenModel(State(Listing.valueOf(listingQuery))) { - private val loggedServices by lazy { Injekt.get().services.filter { it.isLoggedIn } } - var displayMode by sourcePreferences.sourceDisplayMode().asState(coroutineScope) val source = sourceManager.getOrStub(sourceId) @@ -243,8 +233,7 @@ class BrowseMangaSourceScreenModel( new = new.removeCovers(coverCache) } else { setMangaDefaultChapterFlags.await(manga) - - autoAddTrack(manga) + addTracks.bindEnhancedTracks(manga, source) } updateManga.await(new.toMangaUpdate()) @@ -286,28 +275,6 @@ class BrowseMangaSourceScreenModel( } } - private suspend fun autoAddTrack(manga: Manga) { - loggedServices - .filterIsInstance() - .filter { it.accept(source) } - .forEach { service -> - try { - service.match(manga)?.let { track -> - track.manga_id = manga.id - (service as TrackService).mangaService.bind(track) - insertTrack.await(track.toDomainTrack()!!) - syncChapterProgressWithTrack.await( - manga.id, - track.toDomainTrack()!!, - service.mangaService, - ) - } - } catch (e: Exception) { - logcat(LogPriority.WARN, e) { "Could not match manga: ${manga.title} with service $service" } - } - } - } - /** * Get user categories. * diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/entries/anime/AnimeScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/entries/anime/AnimeScreenModel.kt index 615301a91..eed112122 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/entries/anime/AnimeScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/entries/anime/AnimeScreenModel.kt @@ -27,9 +27,9 @@ import eu.kanade.tachiyomi.animesource.model.Video import eu.kanade.tachiyomi.data.download.anime.AnimeDownloadCache import eu.kanade.tachiyomi.data.download.anime.AnimeDownloadManager import eu.kanade.tachiyomi.data.download.anime.model.AnimeDownload -import eu.kanade.tachiyomi.data.track.AnimeTrackService -import eu.kanade.tachiyomi.data.track.EnhancedAnimeTrackService -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.AnimeTracker +import eu.kanade.tachiyomi.data.track.EnhancedAnimeTracker +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.network.HttpException import eu.kanade.tachiyomi.ui.entries.anime.track.AnimeTrackItem import eu.kanade.tachiyomi.ui.player.settings.PlayerPreferences @@ -90,7 +90,7 @@ class AnimeScreenModel( uiPreferences: UiPreferences = Injekt.get(), private val trackPreferences: TrackPreferences = Injekt.get(), internal val playerPreferences: PlayerPreferences = Injekt.get(), - private val trackManager: TrackManager = Injekt.get(), + private val trackerManager: TrackerManager = Injekt.get(), private val downloadManager: AnimeDownloadManager = Injekt.get(), private val downloadCache: AnimeDownloadCache = Injekt.get(), private val getAnimeAndEpisodes: GetAnimeWithEpisodes = Injekt.get(), @@ -112,7 +112,7 @@ class AnimeScreenModel( private val successState: State.Success? get() = state.value as? State.Success - private val loggedServices by lazy { trackManager.services.filter { it.isLoggedIn && it is AnimeTrackService } } + private val loggedInTrackers by lazy { trackerManager.trackers.filter { it.isLoggedIn && it is AnimeTracker } } val anime: Anime? get() = successState?.anime @@ -335,14 +335,14 @@ class AnimeScreenModel( // Finally match with enhanced tracking when available val source = state.source state.trackItems - .map { it.service } - .filterIsInstance() + .map { it.tracker } + .filterIsInstance() .filter { it.accept(source) } .forEach { service -> launchIO { try { service.match(anime)?.let { track -> - (service as AnimeTrackService).register(track, animeId) + (service as AnimeTracker).register(track, animeId) } } catch (e: Exception) { logcat(LogPriority.WARN, e) { @@ -992,7 +992,7 @@ class AnimeScreenModel( getTracks.subscribe(anime.id) .catch { logcat(LogPriority.ERROR, it) } .map { tracks -> - loggedServices + loggedInTrackers // Map to TrackItem .map { service -> AnimeTrackItem( @@ -1001,7 +1001,7 @@ class AnimeScreenModel( ) } // Show only if the service supports this anime's source - .filter { (it.service as? EnhancedAnimeTrackService)?.accept(source!!) ?: true } + .filter { (it.tracker as? EnhancedAnimeTracker)?.accept(source!!) ?: true } } .distinctUntilChanged() .collectLatest { trackItems -> diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/entries/anime/track/AnimeTrackInfoDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/entries/anime/track/AnimeTrackInfoDialog.kt index aa83cb0c8..3de2d5530 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/entries/anime/track/AnimeTrackInfoDialog.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/entries/anime/track/AnimeTrackInfoDialog.kt @@ -47,14 +47,14 @@ import eu.kanade.presentation.track.TrackItemSelector import eu.kanade.presentation.track.TrackScoreSelector import eu.kanade.presentation.track.TrackStatusSelector import eu.kanade.presentation.track.anime.AnimeTrackInfoDialogHome -import eu.kanade.presentation.track.anime.AnimeTrackServiceSearch +import eu.kanade.presentation.track.anime.AnimeTrackerSearch import eu.kanade.presentation.util.Screen import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.track.AnimeTrackService -import eu.kanade.tachiyomi.data.track.DeletableAnimeTrackService -import eu.kanade.tachiyomi.data.track.EnhancedAnimeTrackService -import eu.kanade.tachiyomi.data.track.TrackManager -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.AnimeTracker +import eu.kanade.tachiyomi.data.track.DeletableAnimeTracker +import eu.kanade.tachiyomi.data.track.EnhancedAnimeTracker +import eu.kanade.tachiyomi.data.track.Tracker +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone import eu.kanade.tachiyomi.util.system.openInBrowser @@ -110,7 +110,7 @@ data class AnimeTrackInfoDialogHomeScreen( navigator.push( TrackStatusSelectorScreen( track = it.track!!, - serviceId = it.service.id, + serviceId = it.tracker.id, ), ) }, @@ -118,7 +118,7 @@ data class AnimeTrackInfoDialogHomeScreen( navigator.push( TrackEpisodeSelectorScreen( track = it.track!!, - serviceId = it.service.id, + serviceId = it.tracker.id, ), ) }, @@ -126,7 +126,7 @@ data class AnimeTrackInfoDialogHomeScreen( navigator.push( TrackScoreSelectorScreen( track = it.track!!, - serviceId = it.service.id, + serviceId = it.tracker.id, ), ) }, @@ -134,7 +134,7 @@ data class AnimeTrackInfoDialogHomeScreen( navigator.push( TrackDateSelectorScreen( track = it.track!!, - serviceId = it.service.id, + serviceId = it.tracker.id, start = true, ), ) @@ -143,13 +143,13 @@ data class AnimeTrackInfoDialogHomeScreen( navigator.push( TrackDateSelectorScreen( track = it.track!!, - serviceId = it.service.id, + serviceId = it.tracker.id, start = false, ), ) }, onNewSearch = { - if (it.service is EnhancedAnimeTrackService) { + if (it.tracker is EnhancedAnimeTracker) { sm.registerEnhancedTracking(it) } else { navigator.push( @@ -157,7 +157,7 @@ data class AnimeTrackInfoDialogHomeScreen( animeId = animeId, initialQuery = it.track?.title ?: animeTitle, currentUrl = it.track?.remoteUrl, - serviceId = it.service.id, + serviceId = it.tracker.id, ), ) } @@ -165,10 +165,10 @@ data class AnimeTrackInfoDialogHomeScreen( onOpenInBrowser = { openTrackerInBrowser(context, it) }, onRemoved = { navigator.push( - TrackAnimeServiceRemoveScreen( + TrackerAnimeRemoveScreen( animeId = animeId, track = it.track!!, - serviceId = it.service.id, + serviceId = it.tracker.id, ), ) }, @@ -212,12 +212,12 @@ data class AnimeTrackInfoDialogHomeScreen( } fun registerEnhancedTracking(item: AnimeTrackItem) { - item.service as EnhancedAnimeTrackService + item.tracker as EnhancedAnimeTracker coroutineScope.launchNonCancellable { val anime = Injekt.get().await(animeId) ?: return@launchNonCancellable try { - val matchResult = item.service.match(anime) ?: throw Exception() - item.service.animeService.register(matchResult, animeId) + val matchResult = item.tracker.match(anime) ?: throw Exception() + item.tracker.animeService.register(matchResult, animeId) } catch (e: Exception) { withUIContext { Injekt.get().toast(R.string.error_no_match) } } @@ -247,15 +247,15 @@ data class AnimeTrackInfoDialogHomeScreen( } private fun List.mapToTrackItem(): List { - val loggedServices = Injekt.get().services.filter { - it.isLoggedIn && it is AnimeTrackService + val loggedInTrackers = Injekt.get().trackers.filter { + it.isLoggedIn && it is AnimeTracker } val source = Injekt.get().getOrStub(sourceId) - return loggedServices + return loggedInTrackers // Map to TrackItem .map { service -> AnimeTrackItem(find { it.syncId.toLong() == service.id }, service) } // Show only if the service supports this anime's source - .filter { (it.service as? EnhancedAnimeTrackService)?.accept(source) ?: true } + .filter { (it.tracker as? EnhancedAnimeTracker)?.accept(source) ?: true } } @Immutable @@ -276,7 +276,7 @@ private data class TrackStatusSelectorScreen( val sm = rememberScreenModel { Model( track = track, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, ) } val state by sm.state.collectAsState() @@ -294,11 +294,11 @@ private data class TrackStatusSelectorScreen( private class Model( private val track: DbAnimeTrack, - private val service: TrackService, + private val tracker: Tracker, ) : StateScreenModel(State(track.status.toInt())) { fun getSelections(): Map { - return service.animeService.getStatusListAnime().associateWith { service.getStatus(it) } + return tracker.animeService.getStatusListAnime().associateWith { tracker.getStatus(it) } } fun setSelection(selection: Int) { @@ -307,7 +307,7 @@ private data class TrackStatusSelectorScreen( fun setStatus() { coroutineScope.launchNonCancellable { - service.animeService.setRemoteAnimeStatus(track.toDbTrack(), state.value.selection) + tracker.animeService.setRemoteAnimeStatus(track.toDbTrack(), state.value.selection) } } @@ -329,7 +329,7 @@ private data class TrackEpisodeSelectorScreen( val sm = rememberScreenModel { Model( track = track, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, ) } val state by sm.state.collectAsState() @@ -349,7 +349,7 @@ private data class TrackEpisodeSelectorScreen( private class Model( private val track: DbAnimeTrack, - private val service: TrackService, + private val tracker: Tracker, ) : StateScreenModel(State(track.lastEpisodeSeen.toInt())) { fun getRange(): Iterable { @@ -367,7 +367,7 @@ private data class TrackEpisodeSelectorScreen( fun setEpisode() { coroutineScope.launchNonCancellable { - service.animeService.setRemoteLastEpisodeSeen( + tracker.animeService.setRemoteLastEpisodeSeen( track.toDbTrack(), state.value.selection, ) @@ -392,7 +392,7 @@ private data class TrackScoreSelectorScreen( val sm = rememberScreenModel { Model( track = track, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, ) } val state by sm.state.collectAsState() @@ -411,11 +411,11 @@ private data class TrackScoreSelectorScreen( private class Model( private val track: DbAnimeTrack, - private val service: TrackService, - ) : StateScreenModel(State(service.animeService.displayScore(track.toDbTrack()))) { + private val tracker: Tracker, + ) : StateScreenModel(State(tracker.animeService.displayScore(track.toDbTrack()))) { fun getSelections(): List { - return service.animeService.getScoreList() + return tracker.animeService.getScoreList() } fun setSelection(selection: String) { @@ -424,7 +424,7 @@ private data class TrackScoreSelectorScreen( fun setScore() { coroutineScope.launchNonCancellable { - service.animeService.setRemoteScore(track.toDbTrack(), state.value.selection) + tracker.animeService.setRemoteScore(track.toDbTrack(), state.value.selection) } } @@ -503,7 +503,7 @@ private data class TrackDateSelectorScreen( val sm = rememberScreenModel { Model( track = track, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, start = start, ) } @@ -532,7 +532,7 @@ private data class TrackDateSelectorScreen( private class Model( private val track: DbAnimeTrack, - private val service: TrackService, + private val tracker: Tracker, private val start: Boolean, ) : ScreenModel { @@ -553,15 +553,15 @@ private data class TrackDateSelectorScreen( millis.convertEpochMillisZone(ZoneOffset.UTC, ZoneOffset.systemDefault()) coroutineScope.launchNonCancellable { if (start) { - service.animeService.setRemoteStartDate(track.toDbTrack(), localMillis) + tracker.animeService.setRemoteStartDate(track.toDbTrack(), localMillis) } else { - service.animeService.setRemoteFinishDate(track.toDbTrack(), localMillis) + tracker.animeService.setRemoteFinishDate(track.toDbTrack(), localMillis) } } } fun confirmRemoveDate(navigator: Navigator) { - navigator.push(TrackDateRemoverScreen(track, service.id, start)) + navigator.push(TrackDateRemoverScreen(track, tracker.id, start)) } } } @@ -578,7 +578,7 @@ private data class TrackDateRemoverScreen( val sm = rememberScreenModel { Model( track = track, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, start = start, ) } @@ -597,7 +597,7 @@ private data class TrackDateRemoverScreen( ) }, text = { - val serviceName = sm.getServiceName() + val serviceName = sm.getName() Text( text = if (start) { stringResource(R.string.track_remove_start_date_conf_text, serviceName) @@ -636,18 +636,18 @@ private data class TrackDateRemoverScreen( private class Model( private val track: DbAnimeTrack, - private val service: TrackService, + private val tracker: Tracker, private val start: Boolean, ) : ScreenModel { - fun getServiceName() = service.name + fun getName() = tracker.name fun removeDate() { coroutineScope.launchNonCancellable { if (start) { - service.animeService.setRemoteStartDate(track.toDbTrack(), 0) + tracker.animeService.setRemoteStartDate(track.toDbTrack(), 0) } else { - service.animeService.setRemoteFinishDate(track.toDbTrack(), 0) + tracker.animeService.setRemoteFinishDate(track.toDbTrack(), 0) } } } @@ -669,14 +669,14 @@ data class TrackServiceSearchScreen( animeId = animeId, currentUrl = currentUrl, initialQuery = initialQuery, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, ) } val state by sm.state.collectAsState() var textFieldValue by remember { mutableStateOf(TextFieldValue(initialQuery)) } - AnimeTrackServiceSearch( + AnimeTrackerSearch( query = textFieldValue, onQueryChange = { textFieldValue = it }, onDispatchQuery = { sm.trackingSearch(textFieldValue.text) }, @@ -695,7 +695,7 @@ data class TrackServiceSearchScreen( private val animeId: Long, private val currentUrl: String? = null, initialQuery: String, - private val service: TrackService, + private val tracker: Tracker, ) : StateScreenModel(State()) { init { @@ -712,7 +712,7 @@ data class TrackServiceSearchScreen( val result = withIOContext { try { - val results = service.animeService.searchAnime(query) + val results = tracker.animeService.searchAnime(query) Result.success(results) } catch (e: Throwable) { Result.failure(e) @@ -728,7 +728,7 @@ data class TrackServiceSearchScreen( } fun registerTracking(item: AnimeTrackSearch) { - coroutineScope.launchNonCancellable { service.animeService.register(item, animeId) } + coroutineScope.launchNonCancellable { tracker.animeService.register(item, animeId) } } fun updateSelection(selected: AnimeTrackSearch) { @@ -743,7 +743,7 @@ data class TrackServiceSearchScreen( } } -private data class TrackAnimeServiceRemoveScreen( +private data class TrackerAnimeRemoveScreen( private val animeId: Long, private val track: AnimeTrack, private val serviceId: Long, @@ -756,10 +756,10 @@ private data class TrackAnimeServiceRemoveScreen( Model( animeId = animeId, track = track, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, ) } - val serviceName = sm.getServiceName() + val serviceName = sm.getName() var removeRemoteTrack by remember { mutableStateOf(false) } AlertDialogContent( modifier = Modifier.windowInsetsPadding(WindowInsets.systemBars), @@ -780,7 +780,7 @@ private data class TrackAnimeServiceRemoveScreen( Text( text = stringResource(R.string.track_delete_text, serviceName), ) - if (sm.isServiceDeletable()) { + if (sm.isDeletable()) { Row(verticalAlignment = Alignment.CenterVertically) { Checkbox( checked = removeRemoteTrack, @@ -828,17 +828,17 @@ private data class TrackAnimeServiceRemoveScreen( private class Model( private val animeId: Long, private val track: AnimeTrack, - private val service: TrackService, + private val tracker: Tracker, private val deleteTrack: DeleteAnimeTrack = Injekt.get(), ) : ScreenModel { - fun getServiceName() = service.name + fun getName() = tracker.name - fun isServiceDeletable() = service is DeletableAnimeTrackService + fun isDeletable() = tracker is DeletableAnimeTracker fun deleteAnimeFromService() { coroutineScope.launchNonCancellable { - (service as DeletableAnimeTrackService).delete(track.toDbTrack()) + (tracker as DeletableAnimeTracker).delete(track.toDbTrack()) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/entries/anime/track/AnimeTrackItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/entries/anime/track/AnimeTrackItem.kt index 76b7fcf9a..6e90ae393 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/entries/anime/track/AnimeTrackItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/entries/anime/track/AnimeTrackItem.kt @@ -1,6 +1,6 @@ package eu.kanade.tachiyomi.ui.entries.anime.track -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.Tracker import tachiyomi.domain.track.anime.model.AnimeTrack -data class AnimeTrackItem(val track: AnimeTrack?, val service: TrackService) +data class AnimeTrackItem(val track: AnimeTrack?, val tracker: Tracker) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/entries/manga/MangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/entries/manga/MangaScreenModel.kt index 115cc2e86..d5d67e770 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/entries/manga/MangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/entries/manga/MangaScreenModel.kt @@ -24,9 +24,9 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.download.manga.MangaDownloadCache import eu.kanade.tachiyomi.data.download.manga.MangaDownloadManager import eu.kanade.tachiyomi.data.download.manga.model.MangaDownload -import eu.kanade.tachiyomi.data.track.EnhancedMangaTrackService -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.EnhancedMangaTracker +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.network.HttpException import eu.kanade.tachiyomi.source.MangaSource import eu.kanade.tachiyomi.ui.entries.manga.track.MangaTrackItem @@ -86,7 +86,7 @@ class MangaScreenModel( readerPreferences: ReaderPreferences = Injekt.get(), uiPreferences: UiPreferences = Injekt.get(), private val trackPreferences: TrackPreferences = Injekt.get(), - private val trackManager: TrackManager = Injekt.get(), + private val trackerManager: TrackerManager = Injekt.get(), private val downloadManager: MangaDownloadManager = Injekt.get(), private val downloadCache: MangaDownloadCache = Injekt.get(), private val getMangaAndChapters: GetMangaWithChapters = Injekt.get(), @@ -107,7 +107,7 @@ class MangaScreenModel( private val successState: State.Success? get() = state.value as? State.Success - private val loggedServices by lazy { trackManager.services.filter { it.isLoggedIn && it is MangaTrackService } } + private val loggedInTrackers by lazy { trackerManager.trackers.filter { it.isLoggedIn && it is MangaTracker } } val manga: Manga? get() = successState?.manga @@ -331,14 +331,14 @@ class MangaScreenModel( // Finally match with enhanced tracking when available val source = state.source state.trackItems - .map { it.service } - .filterIsInstance() + .map { it.tracker } + .filterIsInstance() .filter { it.accept(source) } .forEach { service -> launchIO { try { service.match(manga)?.let { track -> - (service as MangaTrackService).register(track, mangaId) + (service as MangaTracker).register(track, mangaId) } } catch (e: Exception) { logcat(LogPriority.WARN, e) { @@ -979,7 +979,7 @@ class MangaScreenModel( getTracks.subscribe(manga.id) .catch { logcat(LogPriority.ERROR, it) } .map { tracks -> - loggedServices + loggedInTrackers // Map to TrackItem .map { service -> MangaTrackItem( @@ -988,7 +988,7 @@ class MangaScreenModel( ) } // Show only if the service supports this manga's source - .filter { (it.service as? EnhancedMangaTrackService)?.accept(source!!) ?: true } + .filter { (it.tracker as? EnhancedMangaTracker)?.accept(source!!) ?: true } } .distinctUntilChanged() .collectLatest { trackItems -> diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/entries/manga/track/MangaTrackInfoDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/entries/manga/track/MangaTrackInfoDialog.kt index 770afcc71..e6151e9f6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/entries/manga/track/MangaTrackInfoDialog.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/entries/manga/track/MangaTrackInfoDialog.kt @@ -47,14 +47,14 @@ import eu.kanade.presentation.track.TrackItemSelector import eu.kanade.presentation.track.TrackScoreSelector import eu.kanade.presentation.track.TrackStatusSelector import eu.kanade.presentation.track.manga.MangaTrackInfoDialogHome -import eu.kanade.presentation.track.manga.MangaTrackServiceSearch +import eu.kanade.presentation.track.manga.MangaTrackerSearch import eu.kanade.presentation.util.Screen import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.track.DeletableMangaTrackService -import eu.kanade.tachiyomi.data.track.EnhancedMangaTrackService -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackManager -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.DeletableMangaTracker +import eu.kanade.tachiyomi.data.track.EnhancedMangaTracker +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.Tracker +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone import eu.kanade.tachiyomi.util.system.openInBrowser @@ -110,7 +110,7 @@ data class MangaTrackInfoDialogHomeScreen( navigator.push( TrackStatusSelectorScreen( track = it.track!!, - serviceId = it.service.id, + serviceId = it.tracker.id, ), ) }, @@ -118,7 +118,7 @@ data class MangaTrackInfoDialogHomeScreen( navigator.push( TrackChapterSelectorScreen( track = it.track!!, - serviceId = it.service.id, + serviceId = it.tracker.id, ), ) }, @@ -126,7 +126,7 @@ data class MangaTrackInfoDialogHomeScreen( navigator.push( TrackScoreSelectorScreen( track = it.track!!, - serviceId = it.service.id, + serviceId = it.tracker.id, ), ) }, @@ -134,7 +134,7 @@ data class MangaTrackInfoDialogHomeScreen( navigator.push( TrackDateSelectorScreen( track = it.track!!, - serviceId = it.service.id, + serviceId = it.tracker.id, start = true, ), ) @@ -143,13 +143,13 @@ data class MangaTrackInfoDialogHomeScreen( navigator.push( TrackDateSelectorScreen( track = it.track!!, - serviceId = it.service.id, + serviceId = it.tracker.id, start = false, ), ) }, onNewSearch = { - if (it.service is EnhancedMangaTrackService) { + if (it.tracker is EnhancedMangaTracker) { sm.registerEnhancedTracking(it) } else { navigator.push( @@ -157,7 +157,7 @@ data class MangaTrackInfoDialogHomeScreen( mangaId = mangaId, initialQuery = it.track?.title ?: mangaTitle, currentUrl = it.track?.remoteUrl, - serviceId = it.service.id, + serviceId = it.tracker.id, ), ) } @@ -165,10 +165,10 @@ data class MangaTrackInfoDialogHomeScreen( onOpenInBrowser = { openTrackerInBrowser(context, it) }, onRemoved = { navigator.push( - TrackMangaServiceRemoveScreen( + TrackerMangaRemoveScreen( mangaId = mangaId, track = it.track!!, - serviceId = it.service.id, + serviceId = it.tracker.id, ), ) }, @@ -212,12 +212,12 @@ data class MangaTrackInfoDialogHomeScreen( } fun registerEnhancedTracking(item: MangaTrackItem) { - item.service as EnhancedMangaTrackService + item.tracker as EnhancedMangaTracker coroutineScope.launchNonCancellable { val manga = Injekt.get().await(mangaId) ?: return@launchNonCancellable try { - val matchResult = item.service.match(manga) ?: throw Exception() - item.service.mangaService.register(matchResult, mangaId) + val matchResult = item.tracker.match(manga) ?: throw Exception() + item.tracker.mangaService.register(matchResult, mangaId) } catch (e: Exception) { withUIContext { Injekt.get().toast(R.string.error_no_match) } } @@ -247,15 +247,15 @@ data class MangaTrackInfoDialogHomeScreen( } private fun List.mapToTrackItem(): List { - val loggedServices = Injekt.get().services.filter { - it.isLoggedIn && it is MangaTrackService + val loggedInTrackers = Injekt.get().trackers.filter { + it.isLoggedIn && it is MangaTracker } val source = Injekt.get().getOrStub(sourceId) - return loggedServices + return loggedInTrackers // Map to TrackItem .map { service -> MangaTrackItem(find { it.syncId == service.id }, service) } // Show only if the service supports this manga's source - .filter { (it.service as? EnhancedMangaTrackService)?.accept(source) ?: true } + .filter { (it.tracker as? EnhancedMangaTracker)?.accept(source) ?: true } } @Immutable @@ -276,7 +276,7 @@ private data class TrackStatusSelectorScreen( val sm = rememberScreenModel { Model( track = track, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, ) } val state by sm.state.collectAsState() @@ -294,11 +294,11 @@ private data class TrackStatusSelectorScreen( private class Model( private val track: DbMangaTrack, - private val service: TrackService, + private val tracker: Tracker, ) : StateScreenModel(State(track.status.toInt())) { fun getSelections(): Map { - return service.mangaService.getStatusListManga().associateWith { service.getStatus(it) } + return tracker.mangaService.getStatusListManga().associateWith { tracker.getStatus(it) } } fun setSelection(selection: Int) { @@ -307,7 +307,7 @@ private data class TrackStatusSelectorScreen( fun setStatus() { coroutineScope.launchNonCancellable { - service.mangaService.setRemoteMangaStatus(track.toDbTrack(), state.value.selection) + tracker.mangaService.setRemoteMangaStatus(track.toDbTrack(), state.value.selection) } } @@ -329,7 +329,7 @@ private data class TrackChapterSelectorScreen( val sm = rememberScreenModel { Model( track = track, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, ) } val state by sm.state.collectAsState() @@ -349,7 +349,7 @@ private data class TrackChapterSelectorScreen( private class Model( private val track: DbMangaTrack, - private val service: TrackService, + private val tracker: Tracker, ) : StateScreenModel(State(track.lastChapterRead.toInt())) { fun getRange(): Iterable { @@ -367,7 +367,7 @@ private data class TrackChapterSelectorScreen( fun setChapter() { coroutineScope.launchNonCancellable { - service.mangaService.setRemoteLastChapterRead( + tracker.mangaService.setRemoteLastChapterRead( track.toDbTrack(), state.value.selection, ) @@ -392,7 +392,7 @@ private data class TrackScoreSelectorScreen( val sm = rememberScreenModel { Model( track = track, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, ) } val state by sm.state.collectAsState() @@ -411,11 +411,11 @@ private data class TrackScoreSelectorScreen( private class Model( private val track: DbMangaTrack, - private val service: TrackService, - ) : StateScreenModel(State(service.mangaService.displayScore(track.toDbTrack()))) { + private val tracker: Tracker, + ) : StateScreenModel(State(tracker.mangaService.displayScore(track.toDbTrack()))) { fun getSelections(): List { - return service.mangaService.getScoreList() + return tracker.mangaService.getScoreList() } fun setSelection(selection: String) { @@ -424,7 +424,7 @@ private data class TrackScoreSelectorScreen( fun setScore() { coroutineScope.launchNonCancellable { - service.mangaService.setRemoteScore(track.toDbTrack(), state.value.selection) + tracker.mangaService.setRemoteScore(track.toDbTrack(), state.value.selection) } } @@ -503,7 +503,7 @@ private data class TrackDateSelectorScreen( val sm = rememberScreenModel { Model( track = track, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, start = start, ) } @@ -532,7 +532,7 @@ private data class TrackDateSelectorScreen( private class Model( private val track: DbMangaTrack, - private val service: TrackService, + private val tracker: Tracker, private val start: Boolean, ) : ScreenModel { @@ -553,15 +553,15 @@ private data class TrackDateSelectorScreen( millis.convertEpochMillisZone(ZoneOffset.UTC, ZoneOffset.systemDefault()) coroutineScope.launchNonCancellable { if (start) { - service.mangaService.setRemoteStartDate(track.toDbTrack(), localMillis) + tracker.mangaService.setRemoteStartDate(track.toDbTrack(), localMillis) } else { - service.mangaService.setRemoteFinishDate(track.toDbTrack(), localMillis) + tracker.mangaService.setRemoteFinishDate(track.toDbTrack(), localMillis) } } } fun confirmRemoveDate(navigator: Navigator) { - navigator.push(TrackDateRemoverScreen(track, service.id, start)) + navigator.push(TrackDateRemoverScreen(track, tracker.id, start)) } } } @@ -578,7 +578,7 @@ private data class TrackDateRemoverScreen( val sm = rememberScreenModel { Model( track = track, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, start = start, ) } @@ -597,7 +597,7 @@ private data class TrackDateRemoverScreen( ) }, text = { - val serviceName = sm.getServiceName() + val serviceName = sm.getName() Text( text = if (start) { stringResource(R.string.track_remove_start_date_conf_text, serviceName) @@ -636,18 +636,18 @@ private data class TrackDateRemoverScreen( private class Model( private val track: DbMangaTrack, - private val service: TrackService, + private val tracker: Tracker, private val start: Boolean, ) : ScreenModel { - fun getServiceName() = service.name + fun getName() = tracker.name fun removeDate() { coroutineScope.launchNonCancellable { if (start) { - service.mangaService.setRemoteStartDate(track.toDbTrack(), 0) + tracker.mangaService.setRemoteStartDate(track.toDbTrack(), 0) } else { - service.mangaService.setRemoteFinishDate(track.toDbTrack(), 0) + tracker.mangaService.setRemoteFinishDate(track.toDbTrack(), 0) } } } @@ -669,14 +669,14 @@ data class TrackServiceSearchScreen( mangaId = mangaId, currentUrl = currentUrl, initialQuery = initialQuery, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, ) } val state by sm.state.collectAsState() var textFieldValue by remember { mutableStateOf(TextFieldValue(initialQuery)) } - MangaTrackServiceSearch( + MangaTrackerSearch( query = textFieldValue, onQueryChange = { textFieldValue = it }, onDispatchQuery = { sm.trackingSearch(textFieldValue.text) }, @@ -695,7 +695,7 @@ data class TrackServiceSearchScreen( private val mangaId: Long, private val currentUrl: String? = null, initialQuery: String, - private val service: TrackService, + private val tracker: Tracker, ) : StateScreenModel(State()) { init { @@ -712,7 +712,7 @@ data class TrackServiceSearchScreen( val result = withIOContext { try { - val results = service.mangaService.searchManga(query) + val results = tracker.mangaService.searchManga(query) Result.success(results) } catch (e: Throwable) { Result.failure(e) @@ -728,7 +728,7 @@ data class TrackServiceSearchScreen( } fun registerTracking(item: MangaTrackSearch) { - coroutineScope.launchNonCancellable { service.mangaService.register(item, mangaId) } + coroutineScope.launchNonCancellable { tracker.mangaService.register(item, mangaId) } } fun updateSelection(selected: MangaTrackSearch) { @@ -743,7 +743,7 @@ data class TrackServiceSearchScreen( } } -private data class TrackMangaServiceRemoveScreen( +private data class TrackerMangaRemoveScreen( private val mangaId: Long, private val track: MangaTrack, private val serviceId: Long, @@ -756,10 +756,10 @@ private data class TrackMangaServiceRemoveScreen( Model( mangaId = mangaId, track = track, - service = Injekt.get().getService(serviceId)!!, + tracker = Injekt.get().get(serviceId)!!, ) } - val serviceName = sm.getServiceName() + val serviceName = sm.getName() var removeRemoteTrack by remember { mutableStateOf(false) } AlertDialogContent( modifier = Modifier.windowInsetsPadding(WindowInsets.systemBars), @@ -780,7 +780,7 @@ private data class TrackMangaServiceRemoveScreen( Text( text = stringResource(R.string.track_delete_text, serviceName), ) - if (sm.isServiceDeletable()) { + if (sm.isDeletable()) { Row(verticalAlignment = Alignment.CenterVertically) { Checkbox( checked = removeRemoteTrack, @@ -828,17 +828,17 @@ private data class TrackMangaServiceRemoveScreen( private class Model( private val mangaId: Long, private val track: MangaTrack, - private val service: TrackService, + private val tracker: Tracker, private val deleteTrack: DeleteMangaTrack = Injekt.get(), ) : ScreenModel { - fun getServiceName() = service.name + fun getName() = tracker.name - fun isServiceDeletable() = service is DeletableMangaTrackService + fun isDeletable() = tracker is DeletableMangaTracker fun deleteMangaFromService() { coroutineScope.launchNonCancellable { - (service as DeletableMangaTrackService).delete(track.toDbTrack()) + (tracker as DeletableMangaTracker).delete(track.toDbTrack()) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/entries/manga/track/MangaTrackItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/entries/manga/track/MangaTrackItem.kt index 68ca8586c..d5bd664ea 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/entries/manga/track/MangaTrackItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/entries/manga/track/MangaTrackItem.kt @@ -1,6 +1,6 @@ package eu.kanade.tachiyomi.ui.entries.manga.track -import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.Tracker import tachiyomi.domain.track.manga.model.MangaTrack -data class MangaTrackItem(val track: MangaTrack?, val service: TrackService) +data class MangaTrackItem(val track: MangaTrack?, val tracker: Tracker) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/anime/AnimeLibraryScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/anime/AnimeLibraryScreenModel.kt index 8f8a680bb..f4519b8df 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/anime/AnimeLibraryScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/anime/AnimeLibraryScreenModel.kt @@ -25,8 +25,8 @@ import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource import eu.kanade.tachiyomi.data.cache.AnimeCoverCache import eu.kanade.tachiyomi.data.download.anime.AnimeDownloadCache import eu.kanade.tachiyomi.data.download.anime.AnimeDownloadManager -import eu.kanade.tachiyomi.data.track.AnimeTrackService -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.AnimeTracker +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.util.episode.getNextUnseen import eu.kanade.tachiyomi.util.removeCovers import kotlinx.coroutines.flow.Flow @@ -89,7 +89,7 @@ class AnimeLibraryScreenModel( private val sourceManager: AnimeSourceManager = Injekt.get(), private val downloadManager: AnimeDownloadManager = Injekt.get(), private val downloadCache: AnimeDownloadCache = Injekt.get(), - private val trackManager: TrackManager = Injekt.get(), + private val trackerManager: TrackerManager = Injekt.get(), ) : StateScreenModel(State()) { var activeCategoryIndex: Int by libraryPreferences.lastUsedAnimeCategory().asState( @@ -104,9 +104,9 @@ class AnimeLibraryScreenModel( getTracksPerAnime.subscribe(), getTrackingFilterFlow(), downloadCache.changes, - ) { searchQuery, library, tracks, loggedInTrackServices, _ -> + ) { searchQuery, library, tracks, loggedInTrackers, _ -> library - .applyFilters(tracks, loggedInTrackServices) + .applyFilters(tracks, loggedInTrackers) .applySort() .mapValues { (_, value) -> if (searchQuery != null) { @@ -172,7 +172,7 @@ class AnimeLibraryScreenModel( */ private suspend fun AnimeLibraryMap.applyFilters( trackMap: Map>, - loggedInTrackServices: Map, + loggedInTrackers: Map, ): AnimeLibraryMap { val prefs = getAnimelibItemPreferencesFlow().first() val downloadedOnly = prefs.globalFilterDownloaded @@ -183,10 +183,10 @@ class AnimeLibraryScreenModel( val filterBookmarked = prefs.filterBookmarked val filterCompleted = prefs.filterCompleted - val isNotLoggedInAnyTrack = loggedInTrackServices.isEmpty() + val isNotLoggedInAnyTrack = loggedInTrackers.isEmpty() - val excludedTracks = loggedInTrackServices.mapNotNull { if (it.value == TriState.ENABLED_NOT) it.key else null } - val includedTracks = loggedInTrackServices.mapNotNull { if (it.value == TriState.ENABLED_IS) it.key else null } + val excludedTracks = loggedInTrackers.mapNotNull { if (it.value == TriState.ENABLED_NOT) it.key else null } + val includedTracks = loggedInTrackers.mapNotNull { if (it.value == TriState.ENABLED_IS) it.key else null } val trackFiltersIsIgnored = includedTracks.isEmpty() && excludedTracks.isEmpty() val filterFnDownloaded: (AnimeLibraryItem) -> Boolean = { @@ -380,14 +380,14 @@ class AnimeLibraryScreenModel( * @return map of track id with the filter value */ private fun getTrackingFilterFlow(): Flow> { - val loggedServices = trackManager.services.filter { it.isLoggedIn && it is AnimeTrackService } - return if (loggedServices.isNotEmpty()) { - val prefFlows = loggedServices + val loggedInTrackers = trackerManager.trackers.filter { it.isLoggedIn && it is AnimeTracker } + return if (loggedInTrackers.isNotEmpty()) { + val prefFlows = loggedInTrackers .map { libraryPreferences.filterTrackedAnime(it.id.toInt()).changes() } .toTypedArray() combine(*prefFlows) { - loggedServices - .mapIndexed { index, trackService -> trackService.id to it[index] } + loggedInTrackers + .mapIndexed { index, tracker -> tracker.id to it[index] } .toMap() } } else { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/anime/AnimeLibrarySettingsScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/anime/AnimeLibrarySettingsScreenModel.kt index c19913cfc..0cebe8077 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/anime/AnimeLibrarySettingsScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/anime/AnimeLibrarySettingsScreenModel.kt @@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.library.anime import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.coroutineScope import eu.kanade.domain.base.BasePreferences -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import tachiyomi.core.preference.Preference import tachiyomi.core.preference.TriState import tachiyomi.core.preference.getAndSet @@ -22,11 +22,11 @@ class AnimeLibrarySettingsScreenModel( val libraryPreferences: LibraryPreferences = Injekt.get(), private val setAnimeDisplayMode: SetAnimeDisplayMode = Injekt.get(), private val setSortModeForCategory: SetSortModeForAnimeCategory = Injekt.get(), - private val trackManager: TrackManager = Injekt.get(), + private val trackerManager: TrackerManager = Injekt.get(), ) : ScreenModel { - val trackServices - get() = trackManager.services.filter { it.isLoggedIn } + val trackers + get() = trackerManager.trackers.filter { it.isLoggedIn } fun toggleFilter(preference: (LibraryPreferences) -> Preference) { preference(libraryPreferences).getAndSet { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/manga/MangaLibraryScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/manga/MangaLibraryScreenModel.kt index 7836ce360..3da5e8b90 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/manga/MangaLibraryScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/manga/MangaLibraryScreenModel.kt @@ -23,8 +23,8 @@ import eu.kanade.presentation.library.LibraryToolbarTitle import eu.kanade.tachiyomi.data.cache.MangaCoverCache import eu.kanade.tachiyomi.data.download.manga.MangaDownloadCache import eu.kanade.tachiyomi.data.download.manga.MangaDownloadManager -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.util.chapter.getNextUnread @@ -89,7 +89,7 @@ class MangaLibraryScreenModel( private val sourceManager: MangaSourceManager = Injekt.get(), private val downloadManager: MangaDownloadManager = Injekt.get(), private val downloadCache: MangaDownloadCache = Injekt.get(), - private val trackManager: TrackManager = Injekt.get(), + private val trackerManager: TrackerManager = Injekt.get(), ) : StateScreenModel(State()) { var activeCategoryIndex: Int by libraryPreferences.lastUsedMangaCategory().asState( @@ -104,9 +104,9 @@ class MangaLibraryScreenModel( getTracksPerManga.subscribe(), getTrackingFilterFlow(), downloadCache.changes, - ) { searchQuery, library, tracks, loggedInTrackServices, _ -> + ) { searchQuery, library, tracks, loggedInTrackers, _ -> library - .applyFilters(tracks, loggedInTrackServices) + .applyFilters(tracks, loggedInTrackers) .applySort() .mapValues { (_, value) -> if (searchQuery != null) { @@ -172,7 +172,7 @@ class MangaLibraryScreenModel( */ private suspend fun MangaLibraryMap.applyFilters( trackMap: Map>, - loggedInTrackServices: Map, + loggedInTrackers: Map, ): MangaLibraryMap { val prefs = getLibraryItemPreferencesFlow().first() val downloadedOnly = prefs.globalFilterDownloaded @@ -183,10 +183,10 @@ class MangaLibraryScreenModel( val filterBookmarked = prefs.filterBookmarked val filterCompleted = prefs.filterCompleted - val isNotLoggedInAnyTrack = loggedInTrackServices.isEmpty() + val isNotLoggedInAnyTrack = loggedInTrackers.isEmpty() - val excludedTracks = loggedInTrackServices.mapNotNull { if (it.value == TriState.ENABLED_NOT) it.key else null } - val includedTracks = loggedInTrackServices.mapNotNull { if (it.value == TriState.ENABLED_IS) it.key else null } + val excludedTracks = loggedInTrackers.mapNotNull { if (it.value == TriState.ENABLED_NOT) it.key else null } + val includedTracks = loggedInTrackers.mapNotNull { if (it.value == TriState.ENABLED_IS) it.key else null } val trackFiltersIsIgnored = includedTracks.isEmpty() && excludedTracks.isEmpty() val filterFnDownloaded: (MangaLibraryItem) -> Boolean = { @@ -372,14 +372,14 @@ class MangaLibraryScreenModel( * @return map of track id with the filter value */ private fun getTrackingFilterFlow(): Flow> { - val loggedServices = trackManager.services.filter { it.isLoggedIn && it is MangaTrackService } - return if (loggedServices.isNotEmpty()) { - val prefFlows = loggedServices + val loggedInTrackers = trackerManager.trackers.filter { it.isLoggedIn && it is MangaTracker } + return if (loggedInTrackers.isNotEmpty()) { + val prefFlows = loggedInTrackers .map { libraryPreferences.filterTrackedManga(it.id.toInt()).changes() } .toTypedArray() combine(*prefFlows) { - loggedServices - .mapIndexed { index, trackService -> trackService.id to it[index] } + loggedInTrackers + .mapIndexed { index, tracker -> tracker.id to it[index] } .toMap() } } else { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/manga/MangaLibrarySettingsScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/manga/MangaLibrarySettingsScreenModel.kt index cb89404ec..e4f2937af 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/manga/MangaLibrarySettingsScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/manga/MangaLibrarySettingsScreenModel.kt @@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.library.manga import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.coroutineScope import eu.kanade.domain.base.BasePreferences -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import tachiyomi.core.preference.Preference import tachiyomi.core.preference.TriState import tachiyomi.core.preference.getAndSet @@ -22,11 +22,11 @@ class MangaLibrarySettingsScreenModel( val libraryPreferences: LibraryPreferences = Injekt.get(), private val setMangaDisplayMode: SetMangaDisplayMode = Injekt.get(), private val setSortModeForCategory: SetSortModeForMangaCategory = Injekt.get(), - private val trackManager: TrackManager = Injekt.get(), + private val trackerManager: TrackerManager = Injekt.get(), ) : ScreenModel { - val trackServices - get() = trackManager.services.filter { it.isLoggedIn } + val trackers + get() = trackerManager.trackers.filter { it.isLoggedIn } fun toggleFilter(preference: (LibraryPreferences) -> Preference) { preference(libraryPreferences).getAndSet { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index ead154ed7..78fed7712 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -157,7 +157,7 @@ class MainActivity : BaseActivity() { readerPreferences = Injekt.get(), playerPreferences = Injekt.get(), backupPreferences = Injekt.get(), - trackManager = Injekt.get(), + trackerManager = Injekt.get(), ) } else { false diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/player/ExternalIntents.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/player/ExternalIntents.kt index 4f05bcd18..91c03af06 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/player/ExternalIntents.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/player/ExternalIntents.kt @@ -20,8 +20,8 @@ import eu.kanade.tachiyomi.animesource.AnimeSource import eu.kanade.tachiyomi.animesource.model.Video import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource import eu.kanade.tachiyomi.data.download.anime.AnimeDownloadManager -import eu.kanade.tachiyomi.data.track.AnimeTrackService -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.AnimeTracker +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.ui.player.loader.EpisodeLoader import eu.kanade.tachiyomi.ui.player.settings.PlayerPreferences import eu.kanade.tachiyomi.util.system.LocaleHelper @@ -492,15 +492,15 @@ class ExternalIntents { private suspend fun updateTrackEpisodeSeen(episodeNumber: Double, anime: Anime) { if (!trackPreferences.autoUpdateTrack().get()) return - val trackManager = Injekt.get() + val trackerManager = Injekt.get() val context = Injekt.get() withIOContext { getTracks.await(anime.id) .mapNotNull { track -> - val service = trackManager.getService(track.syncId) - if (service != null && service.isLoggedIn && - service is AnimeTrackService && episodeNumber > track.lastEpisodeSeen + val tracker = trackerManager.get(track.syncId) + if (tracker != null && tracker.isLoggedIn && + tracker is AnimeTracker && episodeNumber > track.lastEpisodeSeen ) { val updatedTrack = track.copy(lastEpisodeSeen = episodeNumber) @@ -509,7 +509,7 @@ class ExternalIntents { async { runCatching { if (context.isOnline()) { - service.animeService.update(updatedTrack.toDbTrack(), true) + tracker.animeService.update(updatedTrack.toDbTrack(), true) insertTrack.await(updatedTrack) } else { delayedTrackingStore.addAnimeItem(updatedTrack) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerViewModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerViewModel.kt index 6b6d03d8a..98af2f59e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerViewModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerViewModel.kt @@ -24,7 +24,7 @@ import eu.kanade.tachiyomi.data.download.anime.model.AnimeDownload import eu.kanade.tachiyomi.data.saver.Image import eu.kanade.tachiyomi.data.saver.ImageSaver import eu.kanade.tachiyomi.data.saver.Location -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.data.track.anilist.Anilist import eu.kanade.tachiyomi.data.track.myanimelist.MyAnimeList import eu.kanade.tachiyomi.network.NetworkPreferences @@ -658,7 +658,7 @@ class PlayerViewModel @JvmOverloads constructor( */ suspend fun aniSkipResponse(playerDuration: Int?): List? { val animeId = currentAnime?.id ?: return null - val trackManager = Injekt.get() + val trackerManager = Injekt.get() var malId: Long? val episodeNumber = currentEpisode?.episode_number?.toInt() ?: return null if (getTracks.await(animeId).isEmpty()) { @@ -667,8 +667,8 @@ class PlayerViewModel @JvmOverloads constructor( } getTracks.await(animeId).map { track -> - val service = trackManager.getService(track.syncId) - malId = when (service) { + val tracker = trackerManager.get(track.syncId) + malId = when (tracker) { is MyAnimeList -> track.remoteId is Anilist -> AniSkipApi().getMalIdFromAL(track.remoteId) else -> null diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/BaseOAuthLoginActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/BaseOAuthLoginActivity.kt index a1a91a003..92302d718 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/BaseOAuthLoginActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/BaseOAuthLoginActivity.kt @@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.setting.track import android.content.Intent import android.net.Uri import android.os.Bundle -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.ui.base.activity.BaseActivity import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.util.view.setComposeContent @@ -12,7 +12,7 @@ import uy.kohesive.injekt.injectLazy abstract class BaseOAuthLoginActivity : BaseActivity() { - internal val trackManager: TrackManager by injectLazy() + internal val trackerManager: TrackerManager by injectLazy() abstract fun handleResult(data: Uri?) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/TrackLoginActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/TrackLoginActivity.kt index b3bb81ac3..250616cc9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/TrackLoginActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/TrackLoginActivity.kt @@ -21,11 +21,11 @@ class TrackLoginActivity : BaseOAuthLoginActivity() { val matchResult = regex.find(data.fragment.toString()) if (matchResult?.groups?.get(1) != null) { lifecycleScope.launchIO { - trackManager.aniList.login(matchResult.groups[1]!!.value) + trackerManager.aniList.login(matchResult.groups[1]!!.value) returnToSettings() } } else { - trackManager.aniList.logout() + trackerManager.aniList.logout() returnToSettings() } } @@ -34,11 +34,11 @@ class TrackLoginActivity : BaseOAuthLoginActivity() { val code = data.getQueryParameter("code") if (code != null) { lifecycleScope.launchIO { - trackManager.bangumi.login(code) + trackerManager.bangumi.login(code) returnToSettings() } } else { - trackManager.bangumi.logout() + trackerManager.bangumi.logout() returnToSettings() } } @@ -47,11 +47,11 @@ class TrackLoginActivity : BaseOAuthLoginActivity() { val code = data.getQueryParameter("code") if (code != null) { lifecycleScope.launchIO { - trackManager.myAnimeList.login(code) + trackerManager.myAnimeList.login(code) returnToSettings() } } else { - trackManager.myAnimeList.logout() + trackerManager.myAnimeList.logout() returnToSettings() } } @@ -60,11 +60,11 @@ class TrackLoginActivity : BaseOAuthLoginActivity() { val code = data.getQueryParameter("code") if (code != null) { lifecycleScope.launchIO { - trackManager.shikimori.login(code) + trackerManager.shikimori.login(code) returnToSettings() } } else { - trackManager.shikimori.logout() + trackerManager.shikimori.logout() returnToSettings() } } @@ -73,11 +73,11 @@ class TrackLoginActivity : BaseOAuthLoginActivity() { val code = data?.getQueryParameter("code") if (code != null) { lifecycleScope.launchIO { - trackManager.simkl.login(code) + trackerManager.simkl.login(code) returnToSettings() } } else { - trackManager.simkl.logout() + trackerManager.simkl.logout() returnToSettings() } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/stats/anime/AnimeStatsScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/stats/anime/AnimeStatsScreenModel.kt index 0835b08aa..680638995 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/stats/anime/AnimeStatsScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/stats/anime/AnimeStatsScreenModel.kt @@ -11,8 +11,8 @@ import eu.kanade.presentation.more.stats.StatsScreenState import eu.kanade.presentation.more.stats.data.StatsData import eu.kanade.tachiyomi.animesource.model.SAnime import eu.kanade.tachiyomi.data.download.anime.AnimeDownloadManager -import eu.kanade.tachiyomi.data.track.AnimeTrackService -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.AnimeTracker +import eu.kanade.tachiyomi.data.track.TrackerManager import kotlinx.coroutines.flow.update import tachiyomi.core.util.lang.launchIO import tachiyomi.domain.entries.anime.interactor.GetLibraryAnime @@ -34,10 +34,10 @@ class AnimeStatsScreenModel( private val getEpisodeByAnimeId: GetEpisodeByAnimeId = Injekt.get(), private val getTracks: GetAnimeTracks = Injekt.get(), private val preferences: LibraryPreferences = Injekt.get(), - private val trackManager: TrackManager = Injekt.get(), + private val trackerManager: TrackerManager = Injekt.get(), ) : StateScreenModel(StatsScreenState.Loading) { - private val loggedServices by lazy { trackManager.services.fastFilter { it.isLoggedIn && it is AnimeTrackService } } + private val loggedInTrackers by lazy { trackerManager.trackers.fastFilter { it.isLoggedIn && it is AnimeTracker } } init { coroutineScope.launchIO { @@ -73,7 +73,7 @@ class AnimeStatsScreenModel( val trackersStatData = StatsData.Trackers( trackedTitleCount = animeTrackMap.count { it.value.isNotEmpty() }, meanScore = meanScore, - trackerCount = loggedServices.size, + trackerCount = loggedInTrackers.size, ) mutableState.update { @@ -116,10 +116,10 @@ class AnimeStatsScreenModel( } private suspend fun getAnimeTrackMap(libraryAnime: List): Map> { - val loggedServicesIds = loggedServices.map { it.id }.toHashSet() + val loggedInTrackerIds = loggedInTrackers.map { it.id }.toHashSet() return libraryAnime.associate { anime -> val tracks = getTracks.await(anime.id) - .fastFilter { it.syncId in loggedServicesIds } + .fastFilter { it.syncId in loggedInTrackerIds } anime.id to tracks } @@ -160,7 +160,7 @@ class AnimeStatsScreenModel( } private fun get10PointScore(track: AnimeTrack): Double { - val service = trackManager.getService(track.syncId)!! - return service.animeService.get10PointScore(track) + val tracker = trackerManager.get(track.syncId)!! + return tracker.animeService.get10PointScore(track) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/stats/manga/MangaStatsScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/stats/manga/MangaStatsScreenModel.kt index 1e7382592..a3ffd2567 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/stats/manga/MangaStatsScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/stats/manga/MangaStatsScreenModel.kt @@ -10,8 +10,8 @@ import eu.kanade.core.util.fastMapNotNull import eu.kanade.presentation.more.stats.StatsScreenState import eu.kanade.presentation.more.stats.data.StatsData import eu.kanade.tachiyomi.data.download.manga.MangaDownloadManager -import eu.kanade.tachiyomi.data.track.MangaTrackService -import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.data.track.MangaTracker +import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.source.model.SManga import kotlinx.coroutines.flow.update import tachiyomi.core.util.lang.launchIO @@ -34,10 +34,10 @@ class MangaStatsScreenModel( private val getTotalReadDuration: GetTotalReadDuration = Injekt.get(), private val getTracks: GetMangaTracks = Injekt.get(), private val preferences: LibraryPreferences = Injekt.get(), - private val trackManager: TrackManager = Injekt.get(), + private val trackerManager: TrackerManager = Injekt.get(), ) : StateScreenModel(StatsScreenState.Loading) { - private val loggedServices by lazy { trackManager.services.fastFilter { it.isLoggedIn && it is MangaTrackService } } + private val loggedInTrackers by lazy { trackerManager.trackers.fastFilter { it.isLoggedIn && it is MangaTracker } } init { coroutineScope.launchIO { @@ -73,7 +73,7 @@ class MangaStatsScreenModel( val trackersStatData = StatsData.Trackers( trackedTitleCount = mangaTrackMap.count { it.value.isNotEmpty() }, meanScore = meanScore, - trackerCount = loggedServices.size, + trackerCount = loggedInTrackers.size, ) mutableState.update { @@ -116,10 +116,10 @@ class MangaStatsScreenModel( } private suspend fun getMangaTrackMap(libraryManga: List): Map> { - val loggedServicesIds = loggedServices.map { it.id }.toHashSet() + val loggedInTrackerIds = loggedInTrackers.map { it.id }.toHashSet() return libraryManga.associate { manga -> val tracks = getTracks.await(manga.id) - .fastFilter { it.syncId in loggedServicesIds } + .fastFilter { it.syncId in loggedInTrackerIds } manga.id to tracks } @@ -145,7 +145,7 @@ class MangaStatsScreenModel( } private fun get10PointScore(track: MangaTrack): Double { - val service = trackManager.getService(track.syncId)!! - return service.mangaService.get10PointScore(track) + val tracker = trackerManager.get(track.syncId)!! + return tracker.mangaService.get10PointScore(track) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/AniChartApi.kt b/app/src/main/java/eu/kanade/tachiyomi/util/AniChartApi.kt index 113027ded..b2151e8e7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/AniChartApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/AniChartApi.kt @@ -29,14 +29,14 @@ class AniChartApi { return withIOContext { val matchingTrackItem = trackItems.firstOrNull { - (it.service is Anilist && it.track != null) || - (it.service is MyAnimeList && it.track != null) || - (it.service is Simkl && it.track != null) + (it.tracker is Anilist && it.track != null) || + (it.tracker is MyAnimeList && it.track != null) || + (it.tracker is Simkl && it.track != null) } ?: return@withIOContext Pair(1, 0L) matchingTrackItem.let { item -> item.track!!.let { - airingEpisodeData = when (item.service) { + airingEpisodeData = when (item.tracker) { is Anilist -> getAnilistAiringEpisodeData(it.remoteId) is MyAnimeList -> getAnilistAiringEpisodeData(getAlIdFromMal(it.remoteId)) is Simkl -> getSimklAiringEpisodeData(it.remoteId) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 99438bea9..2c4b9db3b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -aboutlib_version = "10.9.0" +aboutlib_version = "10.9.1" okhttp_version = "5.0.0-alpha.11" shizuku_version = "12.2.0" sqlite = "2.3.1" @@ -43,8 +43,8 @@ coil-core = { module = "io.coil-kt:coil" } coil-gif = { module = "io.coil-kt:coil-gif" } coil-compose = { module = "io.coil-kt:coil-compose" } -subsamplingscaleimageview = "com.github.tachiyomiorg:subsampling-scale-image-view:c8e2650" -image-decoder = "com.github.tachiyomiorg:image-decoder:16eda64574" +subsamplingscaleimageview = "com.github.tachiyomiorg:subsampling-scale-image-view:7e57335" +image-decoder = "com.github.tachiyomiorg:image-decoder:fbd6601290" natural-comparator = "com.github.gpanther:java-nat-sort:natural-comparator-1.1" diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/animesource/ConfigurableAnimeSource.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/animesource/ConfigurableAnimeSource.kt index 3ac9e5da4..56ed878df 100644 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/animesource/ConfigurableAnimeSource.kt +++ b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/animesource/ConfigurableAnimeSource.kt @@ -14,8 +14,14 @@ interface ConfigurableAnimeSource : AnimeSource { * * @since extensions-lib 1.5 */ - fun getPreferences(): SharedPreferences = - Injekt.get().getSharedPreferences("source_$id", Context.MODE_PRIVATE) + fun getSourcePreferences(): SharedPreferences = + Injekt.get().getSharedPreferences(preferenceKey(), Context.MODE_PRIVATE) fun setupPreferenceScreen(screen: PreferenceScreen) } + +private fun ConfigurableAnimeSource.preferenceKey(): String = "source_$id" + +// TODO: use getSourcePreferences once all extensions are on ext-lib 1.5 +fun ConfigurableAnimeSource.sourcePreferences(): SharedPreferences = + Injekt.get().getSharedPreferences(preferenceKey(), Context.MODE_PRIVATE) diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt index 28bc24517..49b83edb9 100644 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt +++ b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt @@ -14,8 +14,14 @@ interface ConfigurableSource : MangaSource { * * @since extensions-lib 1.5 */ - fun getPreferences(): SharedPreferences = - Injekt.get().getSharedPreferences("source_$id", Context.MODE_PRIVATE) + fun getSourcePreferences(): SharedPreferences = + Injekt.get().getSharedPreferences(preferenceKey(), Context.MODE_PRIVATE) fun setupPreferenceScreen(screen: PreferenceScreen) } + +private fun ConfigurableSource.preferenceKey(): String = "source_$id" + +// TODO: use getSourcePreferences once all extensions are on ext-lib 1.5 +fun ConfigurableSource.sourcePreferences(): SharedPreferences = + Injekt.get().getSharedPreferences(preferenceKey(), Context.MODE_PRIVATE)